def gen_typedef(self): """ Generates an internal typedef definition for this function. :param typedef_name: Overrides automatic type name generation w/ value. """ _tmp, tmp = None, None # Fix for an insiduous bug with string identifiers (e.g. int_fast32_t) _tmp = self.func_decl.type.type.type\ if isinstance(self.func_decl.type.type, TypeDecl) else\ IdentifierType(names=self.func_decl.type.type.names) # Use TypeDecl/PtrDecl depending on whether return value is a pointer tmp = PtrDecl([], TypeDecl(self.typedef_name, [], _tmp))\ if self.ret_var.ptr else TypeDecl(self.typedef_name, [], _tmp) _tmp_fdecl = PtrDecl([], FuncDecl(self.param_list, tmp)) # Update base type so its registered a MyriadCType subclass self.base_type = type(self.typedef_name, (MyriadCType, ), {'mtype': IdentifierType([self.typedef_name])})() # Create typedef so its registered by the pycparser AST self.fun_typedef = Typedef(name=self.typedef_name, quals=[], storage=['typedef'], type=_tmp_fdecl, coord=None)
def _make_accessors(self, info): """Build get() and set() function based on info. """ name = self._array_name(info) fname = self._make_getter_name(info) size = info.sizeof() params = [("int", f"x{i}") for i in range(len(info.size))] mults = [ BinaryOp("*", a, ID(b[1])) for a, b in zip(info.size[1:], params[:-1]) ] offset = ID(params[-1][1]) for m in mults: offset = BinaryOp("+", m, offset) cases = [ Case(Constant("int", str(i)), [Return(ID(f"{name}_{i}"))]) for i in range(size) ] body = Compound([Switch(offset, Compound(cases))]) self.accessors.add(make_function(info.type, fname, params, body)) cases = [ Case(Constant("int", str(i)), [Assignment("=", ID(f"{name}_{i}"), ID("value")), Break()]) for i in range(size) ] body = Compound([Switch(offset, Compound(cases))]) type_ = (info.type.name if type(info.type) == Struct else info.type.names[0]) setter = make_function(IdentifierType(["void"]), fname.replace("get", "set", 1), params + [(type_, "value")], body) self.accessors.add(setter)
def gen_memo_flag_node(self,self_touch): val = 'true' if self_touch else 'false' type_ = TypeDecl(declname = self.memo_flag_name, quals=[], type=IdentifierType(names=['bool'])) return Decl(name=self.entity, quals=[], storage=[], funcspec=[], type= type_, init=ID(name=val), bitsize=None)
def touch_definition_node(self): type_ = FuncDecl(args=None, type=TypeDecl(declname=self.c_touch_name, quals=[], type=IdentifierType(names=['void']))) return FuncDef(decl=Decl(name=self.c_touch_name, quals=[], storage=[], funcspec=[], type=type_, init=None, bitsize=None), param_decls=None, body=Compound(block_items=[]))
def translate_FunDecl(c_ast): args = [] if c_ast.args is not None: for a in c_ast.args.params: args.append(translate_Decl(a)) subst = unify( c_ast.type, TypeDecl(Var("declname"), [], IdentifierType(Var("ret_type")))) name = subst.lookup("declname") ret_type = subst.lookup("ret_type") return (name, args, ret_type)
def _generateTypeDefForDecl(self, decl: Decl) -> str: typedefs = "" for param in filter(lambda p: utils.is_function_pointer_type(p.type), decl.type.args.params): name = utils.create_typedef_name_for_fnc_ptr(decl, param) param.type.type.type.declname = name typedef = Typedef(name, param.quals, ["typedef"], param.type) param.type = TypeDecl(param.name, param.type.quals, None, IdentifierType([name])) typedefs += f"{self.cGen.visit_Typedef(typedef)};\n" return typedefs
def translate_typ(c_ast): if isinstance(c_ast, FuncDecl): return translate_FunDecl(c_ast) elif isinstance(c_ast, TypeDecl): pat = TypeDecl(Var("declname"), [], IdentifierType(Var("names"))) t = unify(pat, c_ast) return t.lookup("names") elif isinstance(c_ast, ArrayDecl): pat = ArrayDecl(Var("element_type"), Var("dim", True), []) t = unify(pat, c_ast) elem_typ = translate_typ(t.lookup("element_type")) return (elem_typ, t.lookup("dim", None)) else: NYI(c_ast)
def make_decl(name, offset, type_name): nonlocal decls, pad_count, parser, prev_end if isinstance(offset, str): assert offset[:2] == '0x' offset = int(offset, 16) if prev_end < offset: pad_str = f"char _padding{pad_count}[{offset - prev_end}];" decls.append(parser.parse(pad_str).ext[0]) pad_count += 1 type_decl = TypeDecl(name.replace(".", "__"), None, IdentifierType([mangle_name(type_name)])) decls.append(Decl(None, None, None, None, type_decl, None, None)) req_graph.setdefault(type_name, set()).add(parent_name) if offset != -1: size = pointer_size if type_name.endswith('*') else int( types[type_name]['size'], 16) prev_end = offset + size
def basic_type(name: Union[str, List[str]]) -> TypeDecl: names = [name] if isinstance(name, str) else name idtype = IdentifierType(names=names) return TypeDecl(declname=None, quals=[], type=idtype)
def basic_type(names: List[str]) -> TypeDecl: idtype = IdentifierType(names=names) return TypeDecl(declname=None, quals=[], type=idtype)
def basic_type(name: str) -> TypeDecl: idtype = IdentifierType(names=[name]) return TypeDecl(declname=None, quals=[], type=idtype)
def touch_declaration_node(self): return FuncDecl(args=None, type=TypeDecl(declname=self.c_touch_name, quals=[], type=IdentifierType(names=['void'])))
# run-time typechecking for valid C types and extension of the type system # via subclassing. def _ctype_call(self): """ Dummy function to make Myriad CTypes more pythonic """ return self MyriadCType = type("MyriadCType", (object, ), { "mtype": None, "__call__": _ctype_call, }) MFloat = type("MFloat", (MyriadCType, ), { 'mtype': IdentifierType(names=["float"]), })() MDouble = type("MDouble", (MyriadCType, ), { 'mtype': IdentifierType(names=["double"]), })() MInt = type("MInt", (MyriadCType, ), { 'mtype': IdentifierType(names=["int_fast32_t"]), })() MUInt = type("MUInt", (MyriadCType, ), { 'mtype': IdentifierType(names=["uint_fast32_t"]), })() MVoid = type("MVoid", (MyriadCType, ), { 'mtype': IdentifierType(names=["void"]), })() MSizeT = type("MSizeT", (MyriadCType, ), { 'mtype': IdentifierType(names=["size_t"]),
def identify_nested(ast_tree): ast = ast_tree old_stdout = sys.stdout sys.stdout = mystdout = StringIO() aux_ast = duplicate_element(ast) list = [] extern_while = get_extern_while_body(aux_ast) identify_nested_algorithms_bodies(extern_while, list) labelname_inner = config.variables_2['round'] rounds_list_inner = config.rounds_list_2 delete_round_phase_inner = config.delete_round_phase message_inner = config.msg_structure_fields_2 variables_inner = config.variables_2 if list: list.reverse() labels = config.rounds_list_2 labels.append('ERR_ROUND') code = None cop = duplicate_element(ast) if len(list) >= config.number_of_nested_algorithms: extern = get_extern_while_body(cop) if isinstance(extern.block_items[0], If): myif = extern.block_items[0] list1 = [] list2 = [] aux1 = [] aux2 = [] identify_nested_algorithms_bodies(extern.block_items[0].iftrue, list1) if list1: sys.stdout = old_stdout for elem in list1: conditii = [] whiles_to_if(elem.stmt, conditii) identify_recv_exits(elem.stmt, conditii) remove_mbox(elem.stmt, config.mailbox_2, config.clean_mailbox_2) aux1 = elem.stmt parent = find_parent(ast, elem) index = parent.block_items.index(elem) parent.block_items.remove(elem) coord = elem.coord new_id = ID("inner_algorithm", coord) func = FuncCall(new_id, None, coord) assign_unique_coord(func, coord) parent.block_items.insert(index, func) identify_nested_algorithms_bodies( extern.block_items[0].iffalse, list2) if list2: for elem in list2: conditii = [] whiles_to_if(elem.stmt, conditii) identify_recv_exits(elem.stmt, conditii) remove_mbox(elem.stmt, config.mailbox_2, config.clean_mailbox_2) aux2 = elem.stmt parent = find_parent(ast, elem) index = parent.block_items.index(elem) parent.block_items.remove(elem) coord = elem.coord new_id = ID("inner_algorithm", coord) func = FuncCall(new_id, None, coord) assign_unique_coord(func, coord) parent.block_items.insert(index, func) if aux1 and aux2: myif.iftrue = None myif.iffalse = None myif.iftrue = aux1 myif.iffalse = aux2 trees_dict, trees_paths_dict, is_job = get_paths_trees( cop, labels, labels, config.variables_2['round']) print_rounds(labels, trees_dict, trees_paths_dict, config.variables_2['round'], is_job, delete_round_phase_inner, message_inner, variables_inner, rounds_list_inner[0]) code = mystdout.getvalue() sys.stdout = old_stdout return ast, code else: for elem in list: # print generator.visit(elem), "AAAAAAAAAAA" conditii = [] whiles_to_if(elem.stmt, conditii) identify_recv_exits(elem.stmt, conditii) remove_mbox(elem.stmt, config.mailbox_2, config.clean_mailbox_2) # print generator.visit(elem) trees_dict, trees_paths_dict, is_job = get_paths_trees( elem.stmt, labels, labels, config.variables_2['round']) # print_code(trees_dict, trees_paths_dict, labels) print_rounds(labels, trees_dict, trees_paths_dict, config.variables_2['round'], is_job, delete_round_phase_inner, message_inner, variables_inner, rounds_list_inner[0]) parent = find_parent(ast, elem) index = parent.block_items.index(elem) parent.block_items.remove(elem) coord = elem.coord new_id = ID("inner_algorithm", coord) func = FuncCall(new_id, None, coord) assign_unique_coord(func, coord) parent.block_items.insert(index, func) # print generator.visit(parent.block_items[index]) # print generator.visit(ast) # print generator.visit(func) funcdecl = FuncDecl( None, TypeDecl('inner_algorithm', None, IdentifierType(['int']))) decl = Decl('inner_algorithm', None, None, None, funcdecl, None, None) funcdef = FuncDef(decl, None, None) code = mystdout.getvalue() funcdef.body = Compound([code]) # print generator.visit(ast) sys.stdout = old_stdout return ast, code else: sys.stdout = old_stdout print "pe else" return ast_tree