def __init__(self, db): NameManager.__init__(self) self.db = db self.reserved = {} #http://javascript.about.com/library/blreserved.htm reserved_words = ''' abstract as boolean break byte case catch char class continue const debugger default delete do double else enum export extends false final finally float for function goto if implements import in instanceof int interface is long namespace native new null package private protected public return short static super switch synchronized this throw throws transient true try typeof use var void volatile while with alert ''' for name in reserved_words.split(): self.reserved[name] = True #http://javascript.about.com/library/blclassobj.htm # XXX WAAAHHH!!! IE alert :( there are a lot of objects here that are # _not_ in standard JS, see # http://devedge-temp.mozilla.org/library/manuals/2000/javascript/1.5/reference/ predefined_classes_and_objects = ''' Anchor anchors Applet applets Area Array Body Button Checkbox Date document Error EvalError FileUpload Form forms frame frames Function Hidden History history Image images Link links location Math MimeType mimetypes navigator Number Object Option options Password Plugin plugins Radio RangeError ReferenceError RegExp Reset screen Script Select String Style StyleSheet Submit SyntaxError Text Textarea TypeError URIError window ''' for name in predefined_classes_and_objects.split(): self.reserved[name] = True #http://javascript.about.com/library/blglobal.htm global_properties_and_methods = ''' _content closed Components controllers crypto defaultstatus directories document frames history innerHeight innerWidth length location locationbar menubar name navigator opener outerHeight outerWidth pageXOffset pageYOffset parent personalbar pkcs11 prompter screen screenX screenY scrollbars scrollX scrollY self statusbar toolbar top window ''' for name in global_properties_and_methods.split(): self.reserved[name] = True self.make_reserved_names(' '.join(self.reserved)) self.predefined = set(predefined_classes_and_objects)
def __init__(self, global_prefix='pypy_'): NameManager.__init__(self, global_prefix=global_prefix) # keywords cannot be reused. This is the C99 draft's list. self.make_reserved_names(''' auto enum restrict unsigned break extern return void case float short volatile char for signed while const goto sizeof _Bool continue if static _Complex default inline struct _Imaginary do int switch double long typedef else register union ''')
def __init__(self, sqdir, translator, modname=None): self.sqdir = sqdir self.translator = translator self.modname = (modname or translator.graphs[0].name) self.name_manager = NameManager(number_sep="") self.unique_name_mapping = {} self.pending_nodes = [] self.generated_nodes = set() self.constant_insts = {}
def test_unique(): m = NameManager() sn = m.seennames check = [ m.uniquename('something0'), m.uniquename('something', with_number=True), m.uniquename('something', with_number=True), m.uniquename('something2', with_number=True), m.uniquename('something1'), m.uniquename('something1_1'), ] assert check == ['something0', 'something0_1', 'something1', 'something2_0', 'something1_1', 'something1_1_1']
def test_unique(): m = NameManager() sn = m.seennames check = [ m.uniquename("something0"), m.uniquename("something", with_number=True), m.uniquename("something", with_number=True), m.uniquename("something2", with_number=True), m.uniquename("something1"), m.uniquename("something1_1"), ] assert check == ["something0", "something0_1", "something1", "something2_0", "something1_1", "something1_1_1"]
class GenSqueak: def __init__(self, sqdir, translator, modname=None): self.sqdir = sqdir self.translator = translator self.modname = (modname or translator.graphs[0].name) self.name_manager = NameManager(number_sep="") self.unique_name_mapping = {} self.pending_nodes = [] self.generated_nodes = set() self.constant_insts = {} def gen(self): graph = self.translator.graphs[0] self.pending_nodes.append(FunctionNode(self, graph)) self.filename = '%s.st' % graph.name file = self.sqdir.join(self.filename).open('w') self.gen_source(file) self.pending_nodes.append(SetupNode(self, self.constant_insts)) self.gen_source(file) file.close() return self.filename def gen_source(self, file): while self.pending_nodes: node = self.pending_nodes.pop() self.gen_node(node, file) def gen_node(self, node, f): for dep in node.dependencies(): if dep not in self.generated_nodes: self.pending_nodes.append(node) self.schedule_node(dep) return self.generated_nodes.add(node) for line in node.render(): print >> f, line print >> f, "" def schedule_node(self, node): if node not in self.generated_nodes: if node in self.pending_nodes: # We move the node to the front so we can enforce # the generation of dependencies. self.pending_nodes.remove(node) self.pending_nodes.append(node) def unique_func_name(self, funcgraph, schedule=True): function = funcgraph.func squeak_func_name = self.unique_name(function, function.__name__) if schedule: self.schedule_node(FunctionNode(self, funcgraph)) return squeak_func_name def unique_method_name(self, INSTANCE, method_name, schedule=True): # XXX it's actually more complicated than that because of # inheritance ... squeak_method_name = self.unique_name( (INSTANCE, method_name), method_name) if schedule: self.schedule_node(MethodNode(self, INSTANCE, method_name)) return squeak_method_name def unique_class_name(self, INSTANCE): class_node = self.schedule_node(ClassNode(self, INSTANCE)) if isinstance(INSTANCE, Record): # XXX quick hack class_name = "Record" else: class_name = INSTANCE._name.split(".")[-1] squeak_class_name = self.unique_name(INSTANCE, class_name) return "Py%s" % squeak_class_name def unique_field_name(self, INSTANCE, field_name, schedule=True): # XXX nameclashes with superclasses must be considered, too. while not INSTANCE._fields.has_key(field_name): # This is necessary to prevent a field from having different # unique names in different subclasses. INSTANCE = INSTANCE._superclass if schedule: # Generating getters and setters for all fields by default which # is potentially a waste, but easier for now. self.schedule_node(SetterNode(self, INSTANCE, field_name)) self.schedule_node(GetterNode(self, INSTANCE, field_name)) return self.unique_name( (INSTANCE, "field", field_name), field_name) def unique_var_name(self, variable): return self.unique_name(variable, variable.name) def unique_name(self, key, basename): # XXX should account for squeak keywords here if self.unique_name_mapping.has_key(key): unique = self.unique_name_mapping[key] else: camel_basename = camel_case(basename) unique = self.name_manager.uniquename(camel_basename) self.unique_name_mapping[key] = unique return unique
def __init__(self, database, preimplementationlines=[]): self.database = database self.preimpl = preimplementationlines self.extrafiles = [] self.path = None self.namespace = NameManager()
class SourceGenerator: one_source_file = True def __init__(self, database, preimplementationlines=[]): self.database = database self.preimpl = preimplementationlines self.extrafiles = [] self.path = None self.namespace = NameManager() def set_strategy(self, path, split=True): all_nodes = list(self.database.globalcontainers()) # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] othernodes = [] for node in all_nodes: if node.nodekind == 'func': funcnodes.append(node) else: othernodes.append(node) # for now, only split for stand-alone programs. #if self.database.standalone: if split: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes self.path = path def uniquecname(self, name): assert name.endswith('.c') return self.namespace.uniquename(name[:-2]) + '.c' def makefile(self, name): log.writing(name) filepath = self.path.join(name) if name.endswith('.c'): self.extrafiles.append(filepath) return filepath.open('w') def getextrafiles(self): return self.extrafiles def getothernodes(self): return self.othernodes[:] def getbasecfilefornode(self, node, basecname): # For FuncNode instances, use the python source filename (relative to # the top directory): def invent_nice_name(g): # Lookup the filename from the function. # However, not all FunctionGraph objs actually have a "func": if hasattr(g, 'func'): if g.filename.endswith('.py'): localpath = py.path.local(g.filename) pypkgpath = localpath.pypkgpath() if pypkgpath: relpypath = localpath.relto(pypkgpath) return relpypath.replace('.py', '.c') return None if hasattr(node.obj, 'graph'): name = invent_nice_name(node.obj.graph) if name is not None: return name elif node._funccodegen_owner is not None: name = invent_nice_name(node._funccodegen_owner.graph) if name is not None: return "data_" + name return basecname def splitnodesimpl(self, basecname, nodes, nextra, nbetween, split_criteria=SPLIT_CRITERIA): # Gather nodes by some criteria: nodes_by_base_cfile = {} for node in nodes: c_filename = self.getbasecfilefornode(node, basecname) if c_filename in nodes_by_base_cfile: nodes_by_base_cfile[c_filename].append(node) else: nodes_by_base_cfile[c_filename] = [node] # produce a sequence of nodes, grouped into files # which have no more than SPLIT_CRITERIA lines for basecname in nodes_by_base_cfile: iternodes = iter(nodes_by_base_cfile[basecname]) done = [False] def subiter(): used = nextra for node in iternodes: impl = '\n'.join(list(node.implementation())).split('\n') if not impl: continue cost = len(impl) + nbetween yield node, impl del impl if used + cost > split_criteria: # split if criteria met, unless we would produce nothing. raise StopIteration used += cost done[0] = True while not done[0]: yield self.uniquecname(basecname), subiter() def gen_readable_parts_of_source(self, f): split_criteria_big = SPLIT_CRITERIA if py.std.sys.platform != "win32": if self.database.gcpolicy.need_no_typeptr(): pass # XXX gcc uses toooooons of memory??? else: split_criteria_big = SPLIT_CRITERIA * 4 if self.one_source_file: return gen_readable_parts_of_main_c_file(f, self.database, self.preimpl) # # All declarations # database = self.database structdeflist = database.getstructdeflist() name = 'structdef.h' fi = self.makefile(name) print >> f, '#include "%s"' % name gen_structdef(fi, database) fi.close() name = 'forwarddecl.h' fi = self.makefile(name) print >> f, '#include "%s"' % name gen_forwarddecl(fi, database) fi.close() # # Implementation of functions and global structures and arrays # print >> f print >> f, '/***********************************************************/' print >> f, '/*** Implementations ***/' print >> f for line in self.preimpl: print >> f, line print >> f, '#include "src/g_include.h"' print >> f name = self.uniquecname('structimpl.c') print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Structure Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() nextralines = 11 + 1 for name, nodeiter in self.splitnodesimpl('nonfuncnodes.c', self.othernodes, nextralines, 1): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Non-function Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER for node, impl in nodeiter: print >> fc, '\n'.join(impl) print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() nextralines = 8 + len(self.preimpl) + 4 + 1 for name, nodeiter in self.splitnodesimpl('implement.c', self.funcnodes, nextralines, 1, split_criteria_big): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#define PYPY_FILE_NAME "%s"' % name print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc for line in self.preimpl: print >> fc, line print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER for node, impl in nodeiter: print >> fc, '\n'.join(impl) print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() print >> f
class SourceGenerator: one_source_file = True def __init__(self, database, preimplementationlines=[]): self.database = database self.preimpl = preimplementationlines self.extrafiles = [] self.path = None self.namespace = NameManager() def set_strategy(self, path): all_nodes = list(self.database.globalcontainers()) # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] othernodes = [] for node in all_nodes: if node.nodekind == 'func': funcnodes.append(node) else: othernodes.append(node) # for now, only split for stand-alone programs. if self.database.standalone: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes self.path = path def uniquecname(self, name): assert name.endswith('.c') return self.namespace.uniquename(name[:-2]) + '.c' def makefile(self, name): log.writing(name) filepath = self.path.join(name) if name.endswith('.c'): self.extrafiles.append(filepath) return filepath.open('w') def getextrafiles(self): return self.extrafiles def getothernodes(self): return self.othernodes[:] def splitnodesimpl(self, basecname, nodes, nextra, nbetween, split_criteria=SPLIT_CRITERIA): # produce a sequence of nodes, grouped into files # which have no more than SPLIT_CRITERIA lines iternodes = iter(nodes) done = [False] def subiter(): used = nextra for node in iternodes: impl = '\n'.join(list(node.implementation())).split('\n') if not impl: continue cost = len(impl) + nbetween yield node, impl del impl if used + cost > split_criteria: # split if criteria met, unless we would produce nothing. raise StopIteration used += cost done[0] = True while not done[0]: yield self.uniquecname(basecname), subiter() def gen_readable_parts_of_source(self, f): if py.std.sys.platform != "win32": split_criteria_big = SPLIT_CRITERIA * 4 else: split_criteria_big = SPLIT_CRITERIA if self.one_source_file: return gen_readable_parts_of_main_c_file(f, self.database, self.preimpl) # # All declarations # database = self.database structdeflist = database.getstructdeflist() name = 'structdef.h' fi = self.makefile(name) print >> f, '#include "%s"' % name gen_structdef(fi, database) fi.close() name = 'forwarddecl.h' fi = self.makefile(name) print >> f, '#include "%s"' % name gen_forwarddecl(fi, database) fi.close() # # Implementation of functions and global structures and arrays # print >> f print >> f, '/***********************************************************/' print >> f, '/*** Implementations ***/' print >> f for line in self.preimpl: print >> f, line print >> f, '#include "src/g_include.h"' print >> f name = self.uniquecname('structimpl.c') print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Structure Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() nextralines = 11 + 1 for name, nodeiter in self.splitnodesimpl('nonfuncnodes.c', self.othernodes, nextralines, 1): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Non-function Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER for node, impl in nodeiter: print >> fc, '\n'.join(impl) print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() nextralines = 8 + len(self.preimpl) + 4 + 1 for name, nodeiter in self.splitnodesimpl('implement.c', self.funcnodes, nextralines, 1, split_criteria_big): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc for line in self.preimpl: print >> fc, line print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER for node, impl in nodeiter: print >> fc, '\n'.join(impl) print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() print >> f
class SourceGenerator: one_source_file = True def __init__(self, database, preimplementationlines=[]): self.database = database self.preimpl = preimplementationlines self.extrafiles = [] self.path = None self.namespace = NameManager() def set_strategy(self, path, split=True): all_nodes = list(self.database.globalcontainers()) # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] othernodes = [] for node in all_nodes: if node.nodekind == 'func': funcnodes.append(node) else: othernodes.append(node) # for now, only split for stand-alone programs. #if self.database.standalone: if split: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes self.path = path def uniquecname(self, name): assert name.endswith('.c') return self.namespace.uniquename(name[:-2]) + '.c' def makefile(self, name): log.writing(name) filepath = self.path.join(name) if name.endswith('.c'): self.extrafiles.append(filepath) return filepath.open('w') def getextrafiles(self): return self.extrafiles def getothernodes(self): return self.othernodes[:] def splitnodesimpl(self, basecname, nodes, nextra, nbetween, split_criteria=SPLIT_CRITERIA): # produce a sequence of nodes, grouped into files # which have no more than SPLIT_CRITERIA lines iternodes = iter(nodes) done = [False] def subiter(): used = nextra for node in iternodes: impl = '\n'.join(list(node.implementation())).split('\n') if not impl: continue cost = len(impl) + nbetween yield node, impl del impl if used + cost > split_criteria: # split if criteria met, unless we would produce nothing. raise StopIteration used += cost done[0] = True while not done[0]: yield self.uniquecname(basecname), subiter() def gen_readable_parts_of_source(self, f): split_criteria_big = SPLIT_CRITERIA if py.std.sys.platform != "win32": if self.database.gcpolicy.need_no_typeptr(): pass # XXX gcc uses toooooons of memory??? else: split_criteria_big = SPLIT_CRITERIA * 4 if self.one_source_file: return gen_readable_parts_of_main_c_file(f, self.database, self.preimpl) # # All declarations # database = self.database structdeflist = database.getstructdeflist() name = 'structdef.h' fi = self.makefile(name) print >> f, '#include "%s"' % name gen_structdef(fi, database) fi.close() name = 'forwarddecl.h' fi = self.makefile(name) print >> f, '#include "%s"' % name gen_forwarddecl(fi, database) fi.close() # # Implementation of functions and global structures and arrays # print >> f print >> f, '/***********************************************************/' print >> f, '/*** Implementations ***/' print >> f for line in self.preimpl: print >> f, line print >> f, '#include "src/g_include.h"' print >> f name = self.uniquecname('structimpl.c') print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Structure Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() nextralines = 11 + 1 for name, nodeiter in self.splitnodesimpl('nonfuncnodes.c', self.othernodes, nextralines, 1): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Non-function Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER for node, impl in nodeiter: print >> fc, '\n'.join(impl) print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() nextralines = 8 + len(self.preimpl) + 4 + 1 for name, nodeiter in self.splitnodesimpl('implement.c', self.funcnodes, nextralines, 1, split_criteria_big): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' print >> fc, '/*** Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#define PYPY_FILE_NAME "%s"' % name print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc for line in self.preimpl: print >> fc, line print >> fc print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER for node, impl in nodeiter: print >> fc, '\n'.join(impl) print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() print >> f
# # In contexts (2) and (3), a function declaring a PyObject argument type will # receive a wrapped pypy object if the parameter name starts with 'w_', a # reference (= rffi pointer) otherwise; conversion is automatic. Context (2) # only allows calls with a wrapped object. # # Functions with a PyObject return type should return a wrapped object. # # Functions may raise exceptions. In context (3), the exception flows normally # through the calling function. In context (1) and (2), the exception is # caught; if it is an OperationError, it is stored in the thread state; other # exceptions generate a OperationError(w_SystemError); and the funtion returns # the error value specifed in the API. # cpyext_namespace = NameManager('cpyext_') class ApiFunction: def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED, c_name=None): self.argtypes = argtypes self.restype = restype self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) self.callable = callable if error is not _NOT_SPECIFIED: self.error_value = error