Example #1
0
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)