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
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
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)
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)
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)
def replace_return(self): raw = self.template_data placeholder = b"___FFFC_RETURN___" if type(self.func.return_type) != dwarf_to_c.DwarfVoidType: ret = c_ast.Return(expr=c_ast.ID("retval")) raw = raw.replace(placeholder, bytes(self.generator.visit(ret), "utf-8")) else: raw = raw.replace(placeholder, b"return;") self.template_data = raw
def createTest(block,functionName,varVals,varTypes): #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 returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0")) comp=c_ast.Compound([returnStmt]) main= c_ast.FuncDef(mainDec,None,comp) insertTest(main,"func",['1','2'],['int','int'])
def CanonicalizeFun(ast: c_ast.FuncDef, meta_info: meta.MetaInfo): id_gen = common.UniqueId() ConvertPostToPreIncDec(ast) meta_info.CheckConsistency(ast) ConvertPreIncDecToCompoundAssignment(ast, meta_info) meta_info.CheckConsistency(ast) ConvertWhileLoop(ast, id_gen) ConvertForLoop(ast, id_gen) meta_info.CheckConsistency(ast) EliminateExpressionLists(ast) transform_if.IfTransform(ast, id_gen) transform_if.ShortCircuitIfTransform(ast, id_gen) meta_info.CheckConsistency(ast) transform_label.PruneUselessLabels(ast) transform_rename.UniquifyLocalVars(ast, meta_info, id_gen) FixNodeRequiringBoolInt(ast, meta_info) meta_info.CheckConsistency(ast) # if return type is void decl: c_ast.FuncDecl = ast.decl type_decl: c_ast.TypeDecl = decl.type.type if not isinstance(type_decl.type, c_ast.IdentifierType): return if "void" not in type_decl.type.names: return if ast.body.block_items is None: ast.body.block_items = [] stmts = ast.body.block_items if not stmts or not isinstance(stmts[-1], c_ast.Return): ret = c_ast.Return(None) meta_info.type_links[ret] = meta.GetTypeForDecl(ast.decl.type) stmts.append(ret)
def _get_assume_definition(self): param_name = '__cond' int_type = a.TypeDecl(param_name, [], a.IdentifierType(['int'])) param_list = a.ParamList( [a.Decl(param_name, [], [], [], int_type, None, None)]) assume_type = a.TypeDecl('__VERIFIER_assume', [], a.IdentifierType(['void'])) assume_func_decl = a.FuncDecl(param_list, assume_type) assume_decl = a.Decl('__VERIFIER_assume', list(), list(), list(), assume_func_decl, None, None) exit_code = a.ExprList([a.Constant('int', '0')]) true_branch = a.Compound([a.FuncCall(a.ID('exit'), exit_code)]) false_branch = None if_statement = a.If(a.UnaryOp('!', a.ID(param_name)), true_branch, false_branch) return_statement = a.Return(None) body_items = [if_statement, return_statement] assume_body = a.Compound(body_items) return a.FuncDef(assume_decl, None, assume_body)
def define_sizeof_type_from_ast(argument_ast): prefix = "fffc_get_sizeof_" desired_name = CGenerator().visit(argument_ast) suffix = encode_hash(desired_name) function_name = prefix + suffix 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( c_ast.UnaryOp("sizeof", c_ast.UnaryOp("*", c_ast.ID("storage")))) ]), ) comment = "/* " + desired_name + "*/\n" kr_funcdecl = c_ast.FuncDecl(c_ast.ParamList([]), func_tdecl) return comment, kr_funcdecl, funcdef
def work(self, function_node): ret_num = len(self.rets) # if more than 1 return if ret_num > 1: if isinstance(function_node, c_ast.FuncDef): f_type = function_node.decl.type while not isinstance(f_type, c_ast.TypeDecl): f_type = f_type.type new_type = copy.deepcopy(f_type) new_type.type.names = ['int'] function_node.decl.type.type = c_ast.PtrDecl(type=new_type, quals=[]) new_ret_decl = c_ast.Decl(name="CLEVER_RET", funcspec=[], bitsize=None, storage=[], quals=[], init=c_ast.InitList(exprs=self.ret_exps), type=c_ast.ArrayDecl( dim=c_ast.Constant(type='int', value=str(ret_num)), dim_quals=[], type=c_ast.TypeDecl(declname="CLEVER_RET", quals=[], type=c_ast.IdentifierType(names=['int'])))) ret_state = c_ast.Return(expr=c_ast.ID(name=new_ret_decl.name)) for node in self.rets: function_node.body.block_items.remove(node) function_node.body.block_items.append(new_ret_decl) function_node.body.block_items.append(ret_state) return
def complete_functions(func_object, client_template, lib, is_MLCCheker=True): if not is_MLCCheker: func = func_object.raw_node if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] new_func.body.block_items.append(copy.deepcopy(func)) for missing_def in DUV.missing_define: new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=c_ast.TypeDecl( declname=missing_def, quals=[], type=c_ast.IdentifierType( get_type(missing_def))))) if missing_def in DUV.value_changed: new_func.body.block_items.append( c_ast.Return(c_ast.ID(missing_def))) else: new_func = func func_object.raw_node = new_func func = func_object.node if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] new_func.body.block_items.append(copy.deepcopy(func)) for missing_def in DUV.missing_define: new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=c_ast.TypeDecl(declname=missing_def, quals=[], type=c_ast.IdentifierType( ['int'])))) if missing_def in DUV.value_changed: new_func.body.block_items.append( c_ast.Return(c_ast.ID(missing_def))) #if func is a just a program segment, then also add local variables if isinstance(func, c_ast.Compound): for value_changed in DUV.value_changed: if value_changed not in DUV.missing_define: new_func.body.block_items.append( c_ast.Return(c_ast.ID(value_changed))) else: new_func = func func_object.node = checker.version_merge_client(new_func, lib) set_of_define_interest = set() set_of_change_define_interest = set() if func_object.arg_lib is not None and isinstance(func, c_ast.FuncDef): temp_client_func = func_object.node CUV = CleanUpVisitor() CUV.visit(temp_client_func) DUV = DUVisitor() DUV.visit(temp_client_func) for define in DUV.define: set_of_change_define_interest.add(define) for missing_def in DUV.missing_define: set_of_define_interest.add(missing_def) temp_client_func.body.block_items.insert( 0, c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=c_ast.TypeDecl(declname=missing_def, quals=[], type=c_ast.IdentifierType( get_type(missing_def))))) func_object.node = temp_client_func if func != func_object.lib_node: func = func_object.lib_node if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] new_func.body.block_items.append(copy.deepcopy(func)) for missing_def in DUV.missing_define: new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=c_ast.TypeDecl( declname=missing_def, quals=[], type=c_ast.IdentifierType( get_type(missing_def))))) if missing_def in DUV.value_changed: new_func.body.block_items.append( c_ast.Return(c_ast.ID(missing_def))) func_object.lib_node = new_func elif func_object.arg_lib is not None: func_object.lib_node = func else: func_object.lib_node = new_func if func_object.arg_lib is not None: func = func_object.arg_lib if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] if isinstance(func, c_ast.Compound): new_func.body.block_items = copy.deepcopy(func).block_items else: new_func.body.block_items.append(copy.deepcopy(func)) for missing_def in DUV.missing_define: new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=c_ast.TypeDecl( declname=missing_def, quals=[], type=c_ast.IdentifierType( get_type(missing_def))))) if missing_def in DUV.value_changed: new_func.body.block_items.append( c_ast.Return(c_ast.ID(missing_def))) for defintion in DUV.define: if defintion not in DUV.missing_define and ( (defintion + "_old" in set_of_define_interest or defintion + "_new" in set_of_define_interest or defintion in set_of_define_interest) or (defintion in DUV.value_changed and (defintion + "_old" in set_of_change_define_interest) or (defintion + "_new" in set_of_change_define_interest))): new_func.body.block_items.append( c_ast.Return(c_ast.ID(defintion))) func_object.arg_lib = new_func else: func_object.arg_lib = func return func_object
def complete_functions(func_object, client_template, lib, vistor, is_MLCCheker=True): if not is_MLCCheker: func = func_object.raw_node if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] new_func.body.block_items.append(copy.deepcopy(func)) for missing_def in DUV.missing_define: def_type = get_def_type(missing_def, func_object, vistor) new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=def_type)) if missing_def in DUV.value_changed: new_func.body.block_items.append( c_ast.Return(c_ast.ID(missing_def))) else: new_func = func func_object.raw_node = new_func func = func_object.node DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] if isinstance(func, c_ast.FuncDef): new_func.body = copy.deepcopy(func.body) new_func.decl.type.args = copy.deepcopy(func.decl.type.args) else: new_func.body.block_items.append(copy.deepcopy(func)) return_statement = [] count = 0 for missing_def in DUV.missing_define: def_type = get_def_type(missing_def, func_object, vistor) if def_type is None: continue new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=def_type)) if missing_def in DUV.value_changed: #return_statement.append(c_ast.Return(c_ast.ID(missing_def))) return_statement.append( c_ast.FuncCall(name=c_ast.ID(name="_RETTYPE"), args=c_ast.ExprList(exprs=[ c_ast.ID(missing_def), c_ast.Constant(type='int', value=str(count)) ]))) count += 1 #if func is a just a program segment, then also add local variables if isinstance(func, c_ast.Compound): for value_changed in DUV.value_changed: if value_changed not in DUV.missing_define: #return_statement.append(c_ast.Return(c_ast.ID(value_changed))) return_statement.append( c_ast.FuncCall( name=c_ast.ID(name="_RETTYPE"), args=c_ast.ExprList(exprs=[ c_ast.ID(value_changed), c_ast.Constant(type='int', value=str(count)) ]))) count += 1 return_statement.append( c_ast.FuncCall(name=c_ast.ID(name="END"), args=None)) JPV = JumpVisitor() JPV.visit_and_work(new_func, return_statement) new_func.body.block_items = new_func.body.block_items + return_statement #func_object.node = checker.version_merge_client(new_func, lib) func_object.node = new_func set_of_define_interest = set() set_of_change_define_interest = set() if func_object.arg_lib is not None and isinstance(func, c_ast.FuncDef): temp_client_func = func_object.node CUV = CleanUpVisitor() CUV.visit(temp_client_func) DUV = DUVisitor() DUV.visit(temp_client_func) for define in DUV.define: set_of_change_define_interest.add(define) for missing_def in DUV.missing_define: def_type = get_def_type(missing_def, func_object, vistor) set_of_define_interest.add(missing_def) temp_client_func.body.block_items.insert( 0, c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=def_type)) func_object.node = temp_client_func if func != func_object.lib_node: func = func_object.lib_node if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] new_func.body.block_items.append(copy.deepcopy(func)) return_statement = [] for missing_def in DUV.missing_define: def_type = get_def_type(missing_def, func_object, vistor) if def_type is None: continue new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=def_type)) if missing_def in DUV.value_changed: return_statement.append(c_ast.Return( c_ast.ID(missing_def))) JPV = JumpVisitor() JPV.visit_and_work(new_func, return_statement) new_func.body.block_items = new_func.body.block_items + return_statement func_object.lib_node = new_func elif func_object.arg_lib is not None: func_object.lib_node = func else: func_object.lib_node = new_func if func_object.arg_lib is not None: func = func_object.arg_lib if not isinstance(func, c_ast.FuncDef): DUV = DUVisitor() DUV.visit(func) new_func = copy.deepcopy(client_template) new_func.decl.name = client_template.decl.name renamed_type = new_func.decl.type template_type = client_template.decl.type while not isinstance(template_type, c_ast.TypeDecl): renamed_type = renamed_type.type template_type = template_type.type renamed_type.declname = template_type.declname new_func.decl.type.args = c_ast.ParamList([]) new_func.body.block_items = [] if isinstance(func, c_ast.Compound): new_func.body.block_items = copy.deepcopy(func).block_items else: new_func.body.block_items.append(copy.deepcopy(func)) for missing_def in DUV.missing_define: def_type = get_def_type(missing_def, func_object, vistor) new_func.decl.type.args.params.append( c_ast.Decl(name=missing_def, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=def_type)) if missing_def in DUV.value_changed: new_func.body.block_items.append( c_ast.Return(c_ast.ID(missing_def))) for defintion in DUV.define: if defintion not in DUV.missing_define and ( (defintion + "_old" in set_of_define_interest or defintion + "_new" in set_of_define_interest or defintion in set_of_define_interest) or (defintion in DUV.value_changed and (defintion + "_old" in set_of_change_define_interest) or (defintion + "_new" in set_of_change_define_interest))): new_func.body.block_items.append( c_ast.Return(c_ast.ID(defintion))) func_object.arg_lib = new_func else: func_object.arg_lib = func return func_object
def __init__(self, linenum): self.linenum = linenum self.path = [] self.reached = False self.b1 = c_ast.Return( c_ast.ExprList([c_ast.Constant(value='-1', type='int')]))
def split_func(fd, ofile): prog = FlatProgram() has_nested = False (fd, nondet) = replace_nondet(fd) fd_body = fd.body for i in xrange(nondet): id = c_ast.ID('nondet_%d' % i) decl = c_ast.Decl( id.name, [], [], [], c_ast.TypeDecl(id.name, [], c_ast.IdentifierType(['word_t'])), None, None) fd_body.block_items.insert(0, decl) flatten(fd_body, prog) cgen = c_generator.CGenerator() (id_map, rev_id_map) = number_ids(fd) f = FileWriter(ofile, cgen) f.write('#include "synth.h"\n') f.write("/*\n") for id in sorted(rev_id_map.keys()): f.write(" * %s -> %d\n" % (rev_id_map[id], id)) f.write("*/\n\n") nids = len(id_map) prefix = copy.deepcopy(prog.blocks[0]) loop = copy.deepcopy(prog.blocks[1]) #(prefix, prefix_nondet) = replace_nondet(prefix) #(guard, guard_nondet) = replace_nondet(loop.cond) #(body, body_nondet) = replace_nondet(loop.stmt) decls = [] copy_out = [] prefix_block = [] retvis = ReturnVisitor() retvis.visit(prefix) for b in prefix.block_items: prefix_block.append(b) if isinstance(b, c_ast.Decl): id = b.name vid = id_map[id] b.init = c_ast.ArrayRef(c_ast.ID('in_vars'), c_ast.Constant('int', str(vid))) decls.append(b) if is_signed(b): extend = c_ast.FuncCall(c_ast.ID('SIGN_EXTEND'), c_ast.ExprList([c_ast.ID(id)])) decls.append(extend) prefix_block.append(extend) prefix.block_items = prefix_block for id in sorted(rev_id_map.keys()): varname = rev_id_map[id] arr = c_ast.ArrayRef(c_ast.ID('out_vars'), c_ast.Constant('int', str(id))) var = c_ast.ID(varname) copy_out.append(c_ast.Assignment("=", arr, var)) copy_out.append(c_ast.Return(c_ast.Constant('int', str('1')))) prefix.block_items += copy_out f.write("int prefix(word_t in_vars[NARGS], word_t out_vars[NARGS]) {\n") f.write(prefix) f.write("}\n\n") f.write("int guard(word_t in_vars[NARGS]) {\n") guard_body = c_ast.Compound(copy.copy(decls)) guard_body.block_items.append(c_ast.Return(loop.cond)) f.write(guard_body) ofile.write("}\n\n") if is_nested_loop(loop): has_nested = True nested_prog = FlatProgram() flatten(loop.stmt, nested_prog) inner_prefix = nested_prog.blocks[0] inner_body = nested_prog.blocks[1] inner_suffix = nested_prog.blocks[2] inner_guard = c_ast.Compound( copy.copy(decls) + [c_ast.Return(inner_body.cond)]) if isinstance(inner_body.stmt, c_ast.Compound): inner_body = inner_body.stmt.block_items else: inner_body = [inner_body.stmt] inner_body = c_ast.Compound(copy.copy(decls) + inner_body + copy_out) outer_guard = c_ast.Compound( copy.copy(decls) + [c_ast.Return(loop.cond)]) f.write( "int inner_prefix(word_t in_vars[NARGS], word_t out_vars[NARGS]) {\n" ) inner_prefix.block_items = decls + inner_prefix.block_items + copy_out f.write(inner_prefix) f.write("}\n\n") f.write("int inner_guard(word_t in_vars[NARGS]) {\n") f.write(inner_guard) f.write("}\n\n") f.write( "int inner_body(word_t in_vars[NARGS], word_t out_vars[NARGS]) {\n" ) f.write(inner_body) f.write("}\n\n") f.write( "int inner_suffix(word_t in_vars[NARGS], word_t out_vars[NARGS]) {\n" ) inner_suffix.block_items = decls + inner_suffix.block_items + copy_out f.write(inner_suffix) f.write("}\n\n") f.write("int outer_guard(word_t in_vars[NARGS]) {\n") f.write(outer_guard) f.write("}\n\n") else: f.write("int body(word_t in_vars[NARGS], word_t out_vars[NARGS]) {\n") loop_body = c_ast.Compound( copy.copy(decls) + loop.stmt.block_items + copy_out) f.write(loop_body) f.write("}\n\n") return (rev_id_map, has_nested, nondet)
def define_sizeof_do_nothing_type(t): comment, funcdecl, funcdef = define_sizeof_type(t) funcdef.body = c_ast.Compound( [c_ast.Return(c_ast.Constant(value="0", type="int"))]) return comment, funcdecl, funcdef
def visit_FuncCall(self, node): og_node = node if isinstance(node, c_ast.FuncCall): if isinstance(node.name, c_ast.ID): if node.name.name == self.lib_name: l_object = self.node_dict.get(node, None) if l_object is None: if (self.void_ret): l_object, _ = self.create_ClientContextNode( node, node, None, node, None) else: l_object, _ = self.create_ClientContextNode( c_ast.Return(expr=node), c_ast.Return(expr=node), None, node, None) l_object.type_map[c_generator.CGenerator().visit( node)] = "LIB-TYPE" self.node_dict[node] = l_object self.leaves.append(l_object) leaf = set([l_object]) c_node = node child_node = node verified = dict() while c_node is not None: pure_loop_check = (isinstance(c_node, c_ast.While) or isinstance(c_node, c_ast.For)) \ and self.check_loop_localness(c_node, verified) loop_type_check = pure_loop_check or isinstance( c_node, c_ast.DoWhile) if loop_type_check or c_node == self.client: c_object = self.node_dict.get(c_node, None) if (c_object is None): if (loop_type_check): if (isinstance(c_node, c_ast.While)): child_node_with_loop_context = c_ast.If( cond=c_node.cond, iftrue=child_node, iffalse=None) self.parent_child[ child_node_with_loop_context] = c_node c_object, leaf = self.create_ClientContextNode( child_node_with_loop_context, c_node, None, c_node, l_object, leaf) elif isinstance(c_node, c_ast.For): child_node_with_loop_context = c_ast.If( cond=c_node.cond, iftrue=child_node, iffalse=None) child_node_with_loop_context_complete = c_ast.Compound( block_items=[ child_node_with_loop_context ]) if c_node.init is not None: child_node_with_loop_context_complete.block_items = [ c_node.init ] + child_node_with_loop_context_complete.block_items self.parent_child[ child_node_with_loop_context_complete] = c_node c_object, leaf = self.create_ClientContextNode( child_node_with_loop_context_complete, c_node, None, c_node, l_object, leaf) else: c_object, leaf = self.create_ClientContextNode( child_node, c_node, None, c_node, l_object, leaf) else: c_object, leaf = self.create_ClientContextNode( c_node, copy.deepcopy(c_node), None, c_node, l_object, leaf, treeNode=og_node) self.node_dict[c_node] = c_object self.add_parent_child(c_object, l_object) l_object = c_object elif isinstance(c_node, c_ast.Compound) and not isinstance( child_node, c_ast.FuncDef): child_loc = c_node.block_items.index(child_node) pre_loop, post_loop = self.compute_loop_usage_block( c_node, child_loc) if len(pre_loop) > len(post_loop): max_len = len(pre_loop) else: max_len = len(post_loop) if max_len > 0: for i in range(max_len): if i < len(pre_loop): pre_index = pre_loop[i] + 1 else: pre_index = 0 if i < len(post_loop): post_index = post_loop[i] else: post_index = len(c_node.block_items) raw_l_object = l_object context_raw = c_ast.Compound( block_items=c_node. block_items[pre_index:post_index]) context = c_ast.Compound( block_items=copy.deepcopy( c_node. block_items[pre_index:post_index])) self.parent_child[context] = c_node c_object, leaf = self.create_ClientContextNode( context, copy.deepcopy(context), None, copy.deepcopy(context), raw_l_object, leaf, merge_parent=c_node, treeNode=context, raw_context=context_raw) self.add_parent_child(c_object, l_object) l_object = c_object child_node = c_node c_node = self.parent_child.get(c_node, None) self.root = c_object
def visit_FuncDecl(self, node): try: mfun = node.type.declname fun = self.sname + mfun node.type.declname = fun rett = ' '.join(node.type.type.names) except AttributeError: # This means the function returns a pointer mfun = node.type.type.declname fun = self.sname + mfun node.type.type.declname = fun rett = None param = c_ast.Constant("string", '"' + fun + '() called"') elist = c_ast.ExprList([param]) call = c_ast.FuncCall(c_ast.ID('DEBUG_ONCE'), elist) compound = c_ast.Compound([call]) rval = { 'int': c_ast.Constant("int", "0"), 'int32': c_ast.Constant("int", "0"), 'int64': c_ast.Constant("int", "0"), 'uint32': c_ast.Constant("int", "0"), 'size_t': c_ast.Constant("int", "0"), 'double': c_ast.Constant("int", "0"), 'unsigned long': c_ast.Constant("int", "0"), # Enums... 'cef_color_model_t': c_ast.Constant("int", "0"), 'cef_context_menu_media_state_flags_t': c_ast.Constant("int", "0"), 'cef_context_menu_media_type_t': c_ast.Constant("int", "0"), 'cef_context_menu_type_flags_t': c_ast.Constant("int", "0"), 'cef_context_menu_edit_state_flags_t': c_ast.Constant("int", "0"), 'cef_dom_document_type_t': c_ast.Constant("int", "0"), 'cef_dom_node_type_t': c_ast.Constant("int", "0"), 'cef_duplex_mode_t': c_ast.Constant("int", "0"), 'cef_errorcode_t': c_ast.Constant("int", "0"), 'cef_menu_item_type_t': c_ast.Constant("int", "0"), 'cef_postdataelement_type_t': c_ast.Constant("int", "0"), 'cef_resource_type_t': c_ast.Constant("int", "0"), 'cef_transition_type_t': c_ast.Constant("int", "0"), 'cef_urlrequest_status_t': c_ast.Constant("int", "0"), 'cef_value_type_t': c_ast.Constant("int", "0"), 'cef_xml_node_type_t': c_ast.Constant("int", "0"), # special cases... 'time_t': c_ast.Constant("int", "0"), 'cef_time_t': c_ast.Constant("Struct", "(cef_time_t){}"), 'cef_string_userfree_t': c_ast.Constant("Ptr", "NULL"), None: c_ast.Constant("Ptr", "NULL"), }.get(rett, None) if not rval is None: ret = c_ast.Return(rval) compound.block_items.append(ret) elif rett != 'void': print('Return type not handled: ' + rett) sys.exit(1) decl = c_ast.Decl(fun, None, None, ["CEF_CALLBACK"], node, None, None) fdef = c_ast.FuncDef(decl, None, compound) self.funs[mfun] = fun # fix const double pointer: https://github.com/eliben/pycparser/issues/68 self.ret.append(self.gen.visit(fdef).replace('* const ', ' const* '))
def merge_libs_calls(self, node, simple=True, merge_parent=None): 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 block_parent = node.iftrue elif isinstance(node, c_ast.FuncDef): checking_blocks = node.body.block_items block_parent = node.body elif isinstance(node, c_ast.Compound): checking_blocks = node.block_items block_parent = node else: checking_blocks = [] block_parent = None new_leaf = set() mulitiple_call = False for index in range(len(checking_blocks)): LibCV.use_lib = False block = checking_blocks[index] if merge_parent is not None: self.parent_child[block] = merge_parent else: self.parent_child[block] = block_parent LibCV.visit(block) self.parent_child = dict( list(self.parent_child.items()) + list(LibCV.parent_child.items())) if LibCV.use_lib: for lib in LibCV.lib_node: l_object = self.node_dict.get(lib, None) if l_object is None: if self.void_ret: l_object, _ = self.create_ClientContextNode( lib, lib, None, lib, None, treeNode=lib) else: l_object, _ = self.create_ClientContextNode( c_ast.Return(expr=lib), c_ast.Return(expr=lib), None, lib, None, treeNode=lib) l_object.type_map[c_generator.CGenerator().visit( lib)] = "LIB-TYPE" self.node_dict[lib] = l_object self.leaves.append(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 not simple and ((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
def gen_c_func_adaptor(astperfile): adaptorH = r'''//Automatically generated by goSAIadapterBuilder. #include "sai_api_tbl.h" ''' adaptorC = r'''//Automatically generated by goSAIadapterBuilder. #include "sai_api_tbl_init.c" ''' adaptorFuncdefs = [] for file_ast_fn in astperfile.keys(): # for file_ast_fn in ['/home/johnnie/Documents/gitprojects/SAI/inc/sairouterinterface.h', ]: # for file_ast_fn in ['/home/johnnie/Documents/gitprojects/SAI/inc/sairoute.h', ]: file_ast = astperfile[file_ast_fn] fn_core = file_ast_fn.split('/')[-1] fileC = r'''//Automatically generated by goSAIadapterBuilder. #include "sai_api_tbl.h" ''' fileH = r'''//Automatically generated by goSAIadapterBuilder. #include "sai.h" ''' api_ast = [ inst for inst in file_ast if 'api' in inst.name and not "sai_common_api_t" == inst.name and not "sai_api" in inst.name ] api = dict([(apidecl.type.type.names[0], apidecl.name) for apitypedef in api_ast for apidecl in apitypedef.type.type.decls]) # print(api) for functypedef in file_ast: if not 'fn' in functypedef.name: continue funcdecl = functypedef.type.type if type(funcdecl.type) is c_ast.TypeDecl: funcdecl.type.declname = funcdecl.type.declname[:-3] funcdeclreturntype = funcdecl.type.type.names[0] else: funcdecl.type.type.declname = funcdecl.type.type.declname[:-3] funcdeclreturntype = funcdecl.type.type.type.names[0] if funcdeclreturntype != 'sai_status_t': print("Ret", funcdeclreturntype) continue tblname = file_ast[-1].name + 'bl' if 'api' not in tblname: tblname = None for td in file_ast: if 'table' in td.name: tblname = td.name if tblname == None: break fdecl = c_ast.Decl(functypedef.name[:-3], list(), list(), list(), type=funcdecl, init=None, bitsize=None) fbody = c_ast.Compound(block_items=[ c_ast.Return(expr=c_ast.FuncCall( name=c_ast.StructRef( name=c_ast.StructRef(name=c_ast.ID(name='sai_api_tbl'), type='.', field=c_ast.ID(name=tblname)), # type='->',field=c_ast.ID(name=functypedef.name[4:-3])), type='->', field=c_ast.ID(name=api[functypedef.name])), args=c_ast.ExprList( exprs=[c_ast.ID(p.name) for p in funcdecl.args.params]))) ]) funcdef = c_ast.FuncDef(decl=fdecl, param_decls=None, body=fbody) # print(funcdef) adaptorFuncdefs.append(fdecl) funcH = generator.visit(c_ast.FileAST(fdecl)) fileH += funcH funcC = generator.visit(funcdef) fileC += funcC # print(file_ast) if fileC[-2:] != '"\n': hname = 'adaptor/gen-inc/' + fn_core[:-2] + "_adaptor.h" with open(hname, 'w') as f: f.write(fileH) print("written to", hname) cname = 'adaptor/gen-src/' + fn_core[:-2] + "_adaptor.c" with open(cname, 'w') as f: f.write(fileC) print("written to", cname) adaptorH += '#include "' + hname + '"\n' adaptorC += '#include "' + cname + '"\n' with open("adaptor/gen-inc/sai_adaptor.h", 'w') as f: f.write(adaptorH) with open("adaptor/sai_adaptor_all.c", 'w') as f: f.write(adaptorC) return adaptorFuncdefs