def get_files_to_search(sig, jamaicaoutputdir): """ When performing flow analysis, the search order of files will hugely affect the execution time because almost all referenced functions will be in the current file (i.e. Java package), the FPGA porting layer, or the java.lang package or similar. This function returns a list containing all of the files in the Jamaica output directory and the porting layer. However it orders it based on heuristics to try to ensure that resolutions are faster. """ filestosearch = [] #First, put the originating file as this is the most likely source filestosearch.append(c_filename_of_java_method_sig(sig, jamaicaoutputdir)) #Then the FPGA porting layer filestosearch.append(project_path("projectfiles", "src", "fpgaporting.c")) #Then the java.lang package filestosearch.append(deglob_file(os.path.join(jamaicaoutputdir, "PKG_java_lang_V*__.c"))) #Then the other output C files for f in os.listdir(jamaicaoutputdir): ffullpath = os.path.join(jamaicaoutputdir, f) if ffullpath.endswith(".c") and (not ffullpath.endswith("Main__.c")) and not ffullpath in filestosearch: filestosearch.append(ffullpath) return filestosearch
def refactor_src(bindings, jamaicaoutput, targetdir, debug): """ Copy the C source code for the Jamaica project. For files that contain functions that have been implemented on the FPGA, replace their contents with code to invoke the FPGA instead. Outputs files to targetdir """ #Which are the C files we will need to rewrite? filestoedit = set() for _, sig in bindings.iteritems(): filestoedit.add(c_filename_of_java_method_sig(sig, jamaicaoutput)) #Copy the C files over, rewriting those that contain functions we have passed to the hardware mkdir(targetdir) for item in os.listdir(jamaicaoutput): filepath = os.path.join(jamaicaoutput, item) if os.path.isfile(filepath) and (filepath.endswith(".c") or filepath.endswith(".h")): if not filepath in filestoedit: #Just copy the file, no edits required shutil.copy(filepath, targetdir) else: #Any previous edits to the AST need to be disregarded astcache.invalidate_ast_for(filepath) #Which sigs are in this file? toreplace = [] for callid, sig in bindings.iteritems(): if c_filename_of_java_method_sig(sig, jamaicaoutput) == filepath: decl = c_decl_node_of_java_sig(sig, jamaicaoutput) bounds = get_line_bounds_for_function(decl) toreplace.append((bounds, callid, sig, decl)) toreplace.sort() #Sort by ascending line number filecontents = open(filepath).readlines() output = "#include <juniper_fpga_interface.h>\n#include <juniperoperations.h>\n#include \"jamaica.h\"\n#include <sys/mman.h>\n\n" output += "extern void caicos_handle_pcie_interrupt(jamaica_thread *ct, int devNo, int partNo);\n\n" if debug: output += "#include \"caicos_debug.h\"\n\n" lineno = 1 for bounds, callid, sig, decl in toreplace: while lineno <= bounds[0]: output = output + filecontents[lineno-1] lineno += 1 output += "\t//~~~~~~~~~~~~~~~~" + str(sig) + " " + str(bounds) + "~~~~~~~~~~~~~~~~~~~~~\n" output += "\t" + str(generate_replacement_code(sig, decl, callid, jamaicaoutput, (0, 0))) if bounds[1] == None: #If a replacement is the last thing in the file we'll need to close some things #TODO: Is this branch required any more? Suspect not. output += "}\n\n#else\n#error 'jamaica.h' not found!\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n" lineno = len(filecontents) #Done copying else: output += "}\n" lineno = bounds[1] + 1 #Copy the rest of the file in while lineno-1 < len(filecontents): output = output + filecontents[lineno-1] lineno += 1 with open(os.path.join(targetdir, item), "w") as outf: outf.write(output)