[pypy-svn] r37666 - pypy/dist/pypy/objspace/std
arigo at codespeak.net
arigo at codespeak.net
Wed Jan 31 14:01:28 CET 2007
Author: arigo
Date: Wed Jan 31 14:01:24 2007
New Revision: 37666
Modified:
pypy/dist/pypy/objspace/std/multimethod.py
Log:
Build a sensible summarizing name for the generated functions, instead
of picking a random names among the possible ones.
Modified: pypy/dist/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/dist/pypy/objspace/std/multimethod.py (original)
+++ pypy/dist/pypy/objspace/std/multimethod.py Wed Jan 31 14:01:24 2007
@@ -504,10 +504,41 @@
lst.sort()
return self.body, tuple(lst)
+ def get_function_name(self):
+ # pick a name consistently based on self.possiblenames
+ length = min([len(parts) for parts in self.possiblenames])
+ result = []
+ for i in range(length):
+ choices = {}
+ for parts in self.possiblenames:
+ choices[parts[i]] = True
+ parts = choices.keys()
+ res = str(len(parts))
+ for part in parts:
+ if type(part) is str: # there is a string at this pos
+ if '0_fail' in choices:
+ res = '0_fail'
+ elif len(parts) == 1:
+ res = part
+ break
+ else:
+ # only types at this location, try to find a common base
+ basecls = parts[0]
+ for cls in parts[1:]:
+ if issubclass(basecls, cls):
+ basecls = cls
+ for cls in parts[1:]:
+ if not issubclass(cls, basecls):
+ break # no common base
+ else:
+ res = basecls.__name__
+ result.append(res)
+ return '_'.join(result)
+
def make_function(self, fnargs, nbargs_before, mrdtable):
if self._function is not None:
return self._function
- name = min(self.possiblenames) # pick a random one, but consistently
+ name = self.get_function_name()
self.compress_typechecks(mrdtable)
checklines = self.generate_typechecks(fnargs[nbargs_before:])
if not checklines:
@@ -516,9 +547,18 @@
checklines.append(self.body)
body = '\n '.join(checklines)
source = 'def %s(%s):\n %s\n' % (name, ', '.join(fnargs), body)
- #f = open('/tmp/mm-source/%s' % name, 'a')
- #print >> f, source
- #f.close()
+
+ if 0: # for debugging the generated mm sources
+ f = open('/tmp/mm-source/%s' % name, 'a')
+ for possiblename in self.possiblenames:
+ print >> f, '#',
+ for part in possiblename:
+ print >> f, getattr(part, '__name__', part),
+ print >> f
+ print >> f
+ print >> f, source
+ f.close()
+
exec compile2(source) in self.miniglobals
self._function = self.miniglobals[name]
return self._function
@@ -657,7 +697,7 @@
def install(self):
nskip = len(self.multimethod.argnames_before)
- null_entry = self.build_funcentry(self.prefix + '_0_fail', [])
+ null_entry = self.build_funcentry([self.prefix, '0_fail'], [])
null_entry.no_typecheck()
if self.is_empty():
return self.answer(null_entry)
@@ -671,9 +711,7 @@
if len(typesprefix) == self.multimethod.arity:
calllist = self.table.get(typesprefix, [])
funcname = [self.prefix]
- for t1 in typesprefix:
- funcname.append(t1.__name__)
- funcname = '_'.join(funcname)
+ funcname.extend(typesprefix)
entry = self.build_funcentry(funcname, calllist)
entry.register_valid_types(typesprefix)
return entry
@@ -716,7 +754,7 @@
exprfn = "funcarray.items[(%s + arg%d.%s) & mmmask]" % (exprfn, n,
attrname)
expr = Call(exprfn, self.fnargs)
- entry = self.build_funcentry(self.prefix + '_0_perform_call',
+ entry = self.build_funcentry([self.prefix, '0_perform_call'],
[expr],
indexarray = indexarray,
funcarray = funcarray,
@@ -733,7 +771,7 @@
expr = entry.body[len('return '):]
return self.fnargs, expr, entry.miniglobals, entry.fallback
- def build_funcentry(self, funcname, calllist, **extranames):
+ def build_funcentry(self, funcnameparts, calllist, **extranames):
def expr(v):
if isinstance(v, Call):
return '%s(%s)' % (invent_name(miniglobals, v.function),
@@ -762,7 +800,7 @@
entry = self.mmfunccache[key]
except KeyError:
self.mmfunccache[key] = entry
- entry.possiblenames.append(funcname)
+ entry.possiblenames.append(funcnameparts)
return entry
# ____________________________________________________________
More information about the Pypy-commit
mailing list