def rewrite_source_file(inputfile, outputfile, reachable_functions, syscalls, interfaceResolver, classrefs): """ Parse inputfile, rewrite the AST, save the result to outputfile. All paths should be absolute. This function performs rewrites for the HLS hardware design """ def is_funcdef_in_reachable_list(funcdef): for r in reachable_functions: if r.coord.file == inputfile and r.decl.name == funcdef.decl.name: return True return False ast = astcache.get(inputfile) rewrite_RAM_structure_dereferences(ast) outf = open(outputfile, "w") outf.write('#include "jamaica.h"\n') outf.write('#include "jni.h"\n') outf.write('#include "jbi.h"\n') outf.write('#include "Main__.h"\n') outf.write('\n') generator = pycparser.c_generator.CGenerator() for c in ast.children(): if isinstance(c[1], c_ast.FuncDef): if reachable_functions == None or is_funcdef_in_reachable_list(c[1]): class_references.replace_class_references(c[1], classrefs) rewrite_ct_refs(c[1]) interfaceResolver.rewrite_interface_calls(c[1]) rewrite_syscall_calls(c[1], syscalls) outf.write(generator.visit(c[1])) outf.write("\n") outf.close()
def c_name_of_java_method(sig, c_output_base): """ Find the name of the C method into which the given method signature was translated. This is only partly deterministic so we need to search the AST. """ sig = sig.strip() filetoparse = c_filename_of_java_method_sig(sig, c_output_base) ast = astcache.get(filetoparse) names = get_java_names_of_C_fns(ast) return names[sig]
def c_decl_node_of_java_sig(sig, c_output_base): """ Given a Java signature, get the decl node in the AST of the C function which implements it. Note that this function performs a complete AST traversal of the target file. It is wasteful to call this to resolve a large number of signatures in the same package so the results are cached. If code is being morphed, javanames_cache should be cleared to force a re-parse. """ filename = c_filename_of_java_method_sig(sig, c_output_base) if not astcache.get(filename) in javanames_cache: javanames_cache[astcache.get(filename)] = get_java_names_of_C_fns(astcache.get(filename)) names = javanames_cache[astcache.get(filename)] if not sig in names: raise CaicosError("There is no method with the signature " + str(sig) + " in file " + str(filename)) node = names[sig][1] declnode = node.children()[0][1] if not isinstance(declnode, c_ast.Decl): raise CaicosError("Unexpected function declaration format in file " + str(filename) + " for signature " + str(sig)) return declnode
def get_funcdecl_of_system_funccall(call): """ Given a FuncCall to a Jamaica system call (or just the string of its name), return the corresponding FuncDecl node. """ ast = astcache.get(project_path("projectfiles", "include", "jamaica.h")) fdecs = functions_declared_in_ast(ast) if isinstance(call, c_ast.FuncCall): call = call.name.name for dec in fdecs: if dec.parent.name == call: return dec raise CaicosError("Cannot find the definition of system function: " + str(call))
def parse_files(callname): """ Parse all the .c files provided looking for a suitable function definition. Relies on ASTCache to avoid reparsing the same files again and again. """ log().info("Resolving call to: " + callname) for srcfile in self.filestosearch: ast = astcache.get(srcfile) fns = functions_defined_in_ast(ast) for fn in fns: if fn.decl.name == callname: return fn return None