def dumpXmlBlocks(basic_blocks, filename, options): import clr clr.AddReference('System.Xml') from System.Xml import XmlTextWriter, Formatting writer = XmlTextWriter(filename, None) writer.Formatting = Formatting.Indented writeHeader(writer) print basic_blocks for entry_block in basic_blocks.values(): for block in depthFirstSearch(entry_block): writeBlock(writer, block) for entry_block in basic_blocks.values(): for block in depthFirstSearch(entry_block): for statement in block.statements: writeStatementEdges(writer, statement) writeFooter(writer)
def generateMethodBody(self, type_builder, basic_blocks): # The first statement of the first basic block is the entry point entry_point_node = basic_blocks[0].entryPoint try: name = entry_point_node.name if name == 'Main': name = 'FNMain' clr_method_name = self.owl_to_clr_method_names[name] except KeyError: print entry_point_node.name print self.owl_to_clr_method_names assert 0 logging.debug("Creating CIL for %s", clr_method_name) method_builder = self.method_builders[clr_method_name] logging.debug("entry_point_node = %s", entry_point_node) # Create the visitor which holds the code generator cv = CilVisitor(self, type_builder, method_builder, self.line_mapper, self.doc) # Declare LOCAL variables and attach load and store emitters to the symbols for node in depthFirstSearch(entry_point_node): if isinstance(node, Local): symbol_table = node.symbolTable for symbol in symbol_table.symbols.values(): local_builder = cv.generator.DeclareLocal(cts.symbolType(symbol)) local_builder.SetLocalSymInfo(symbol.name) # Provide symbol name for debugger self.createAndAttachLocalEmitters(local_builder, symbol) # TODO: Declare PRIVATE variables and attach load and store emitters to the symbols # For each basic block (including the first, if it has an in-degree > 1) # define a label, and attach it to the block for basic_block in basic_blocks: basic_block.label = cv.generator.DefineLabel() basic_block.is_label_marked = False # Generate the code for blocks and statements in sequence for basic_block in basic_blocks: for statement in basic_block.statements: if statement.startLine and statement.startColumn and statement.endLine and statement.endColumn: cv.generator.MarkSequencePoint(self.doc, statement.startLine, statement.startColumn, statement.endLine, statement.endColumn) cv.checkMark(statement) # TODO: Could push this out a level to be per block cv.visit(statement) assert statement.block.is_label_marked self.transferControlToNextBlock(cv.generator, basic_block) logging.debug("COMPLETE\n\n\n")
def inferTypeOfFunction(entry_point): ''' Infer the type of the function defined at entry_point by discovering the type of all of the return points from the function. If the types are different numeric types, promote IntegerTypes to FloatTypes. If the types are a mixture of StringTypes and NumericTypes box the return value in an object type. :param entry_point: A DefineFunction AstNode at the start of a user defined function. :returns: The infered type of the function. One of IntegerType, FloatType, StringType or ObjectType. If the type of the function could not be inferred (possibly because other function types need inferring too) return PendingType. ''' print "DEF ", entry_point.name return_types = set() for vertex in depthFirstSearch(entry_point): if isinstance(vertex, ReturnFromFunction): return_types.add(vertex.returnValue.actualType) for type in return_types: print " =", type # If there is only one return type, set the type of the function, and exit if len(return_types) == 0: errors.warning("%s never returns at line %s" % (entry_point.name, entry_point.lineNum)) elif PendingOwlType() in return_types: return_type = PendingOwlType() elif len(return_types) == 1: return_type = representative(return_types) elif reduce(operator.and_, [type.isA(NumericOwlType()) for type in return_types]): # TODO: Modify all function returns to cast to FloatOwlType, if necessary return_type = FloatOwlType() else: # TODO: Modify all function returns to box to ObjectOwlType, if necessary # TODO: Modify all function calls to unbox from ObjectOwlType, to what? return_type = ObjectOwlType() entry_point.returnType = return_type return return_type