[pypy-svn] r13308 - in pypy/dist/pypy: annotation translator

pedronis at codespeak.net pedronis at codespeak.net
Sun Jun 12 00:34:59 CEST 2005


Author: pedronis
Date: Sun Jun 12 00:34:56 2005
New Revision: 13308

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/policy.py
   pypy/dist/pypy/annotation/specialize.py
   pypy/dist/pypy/translator/annrpython.py
Log:
make override a special case of specialization, fix bug uncovered by this in query_spaceop_callable that
was not appending a s_self argument when classdef was present

renaming _annspecialcase_ to _specialize_ again will happen later



Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Sun Jun 12 00:34:56 2005
@@ -327,8 +327,8 @@
         else:
             implicit_init = None
 
-        pbc, dontcarememo = self.query_spaceop_callable(spaceop,
-                                                        implicit_init=implicit_init) 
+        pbc, dontcaresc = self.query_spaceop_callable(spaceop,
+                                                      implicit_init=implicit_init) 
 
         nonnullcallables = []
         for func, classdef in pbc.prebuiltinstances.items():
@@ -387,10 +387,10 @@
         return unionof(*results) 
 
     # decide_callable(position, func, args, mono) -> callb, key
-    # query_spaceop_callable(spaceop) -> pbc, memo
+    # query_spaceop_callable(spaceop) -> pbc, isspecialcase
     # get_s_init(decided_cls) -> classdef, s_undecided_init
 
-    def query_spaceop_callable(self, spaceop, implicit_init=None): # -> s_pbc, memo
+    def query_spaceop_callable(self, spaceop, implicit_init=None): # -> s_pbc, specialcase
         self.enter(None)
         try:
             if implicit_init is None:
@@ -408,10 +408,15 @@
             argsvars = spaceop.args[1:]
             args_s = [self.annotator.binding(v) for v in argsvars]
             args = self.build_args(spaceop.opname, args_s)
-            if init_classdef:
-                args = args.prepend(SomeInstance(init_classdef))
 
             func, classdef = s_obj.prebuiltinstances.items()[0]
+
+            if init_classdef:
+                args = args.prepend(SomeInstance(init_classdef))
+            elif isclassdef(classdef): 
+                s_self = SomeInstance(classdef)
+                args = args.prepend(s_self)
+            
             func, key = decide_callable(self, spaceop, func, args, mono=True)
 
             if key is None:
@@ -444,6 +449,21 @@
         else:
             return classdef, None
  
+    def get_inputcells(self, func, args):
+        # parse the arguments according to the function we are calling
+        signature = cpython_code_signature(func.func_code)
+        defs_s = []
+        if func.func_defaults:
+            for x in func.func_defaults:
+                defs_s.append(self.immutablevalue(x))
+        try:
+            inputcells = args.match_signature(signature, defs_s)
+        except ArgErr, e:
+            raise TypeError, "signature mismatch: %s" % e.getmsg(args, func.__name__)
+
+        return inputcells
+ 
+
     def pycall(self, func, args, mono):
         if func is None:   # consider None as a NULL function pointer
             return SomeImpossibleValue()
@@ -474,17 +494,7 @@
 
         assert isinstance(func, FunctionType), "[%s] expected function, got %r" % (self.whereami(), func)
 
-        # parse the arguments according to the function we are calling
-        signature = cpython_code_signature(func.func_code)
-        defs_s = []
-        if func.func_defaults:
-            for x in func.func_defaults:
-                defs_s.append(self.immutablevalue(x))
-        try:
-            inputcells = args.match_signature(signature, defs_s)
-        except ArgErr, e:
-            assert False, 'ABOUT TO IGNORE %r' % e     # we should take care that we don't end up here anymore
-            return SomeImpossibleValue()
+        inputcells = self.get_inputcells(func, args)
 
         r = self.annotator.recursivecall(func, self.position_key, inputcells)
 

Modified: pypy/dist/pypy/annotation/policy.py
==============================================================================
--- pypy/dist/pypy/annotation/policy.py	(original)
+++ pypy/dist/pypy/annotation/policy.py	Sun Jun 12 00:34:56 2005
@@ -7,38 +7,41 @@
     Possibly subclass and pass an instance to the annotator to control special casing during annotation
     """
 
-    def getspecialcase(pol, kind, obj):
-        if hasattr(obj, '_annspecialcase_'):
-            sc = obj._annspecialcase_.split(':')
-            assert len(sc) ==2, "_annspecialcase_ should have the form kind:tag"
-            if sc[0] == kind:
-                return sc[1]
-            assert sc[0] in ('override', 'specialize'), "_annspecialcase_ kinds are only 'override', 'specialize'"
-        return None
-
-    def override(pol, func, inputcells):
-        tag = pol.getspecialcase('override', func)
-        if tag is None:
-            return None
-        try:
-            override = getattr(pol, 'override__%s' % tag)
-        except AttributeError:
-            raise AttributeError, "%s override tag found in user program but not defined in annotation policy %s" % (tag, pol) 
-
-        return override(*inputcells)
-
     def specialize(pol, bookkeeper, spaceop, func, args, mono):
-        tag = pol.getspecialcase('specialize', func)
-        if tag is None:
-            return pol.default_specialize(bookkeeper, spaceop, func, args, mono)
+        if hasattr(func, '_annspecialcase_'):
+            directive = func._annspecialcase_
+            if directive.startswith('specialize:'):
+                directive = directive[len('specialize:'):]
+            tag_mod = directive.split(':', 1)
+            if len(tag_mod) == 1:
+                tag, = tag_mod
+                mod = None
+            else:
+                tag, mod = tag_mod
+        else:
+            return pol.default_specialize(bookkeeper, None, spaceop, func, args, mono)
         
         try:
             specialize = getattr(pol, 'specialize__%s' % tag)
         except AttributeError:
             raise AttributeError, "%s specialize tag found in user program but not defined in annotation policy %s" % (tag, pol) 
 
-        return specialize(bookkeeper, spaceop, func, args, mono)
-        
+        return specialize(bookkeeper, mod, spaceop, func, args, mono)
+
+    def specialize__override(pol, bookkeeper, mod, spaceop, func, args, mono):
+        from pypy.annotation.model import SomeObject
+        override_tag = mod
+
+        try:
+            override = getattr(pol, 'override__%s' % override_tag)
+        except AttributeError:
+            raise AttributeError, "'override:%s'  found in user program but not defined in annotation policy %s" % (override_tag, pol) 
+
+        inputcells = bookkeeper.get_inputcells(func, args)
+        r = override(*inputcells)
+
+        assert isinstance(r, SomeObject)
+        return r
         
     # common specializations
 

Modified: pypy/dist/pypy/annotation/specialize.py
==============================================================================
--- pypy/dist/pypy/annotation/specialize.py	(original)
+++ pypy/dist/pypy/annotation/specialize.py	Sun Jun 12 00:34:56 2005
@@ -19,10 +19,10 @@
 
     key = bookkeeper.annotator.policy.specialize(bookkeeper, spaceop, func, args, mono)
     if key is not None:
-        assert mono, "not-static call to specialized %s" % func
         if isinstance(key, SomeObject): 
             # direct computation
             return None, key
+        assert mono, "not-static call to specialized %s" % func
         if isinstance(key, tuple): 
             # cache specialization
             try:
@@ -47,7 +47,7 @@
 
     return func, key
 
-def default_specialize(bookkeeper, spaceop, func, args, mono):
+def default_specialize(bookkeeper, dontcare, spaceop, func, args, mono):
     from pypy.interpreter.pycode import CO_VARARGS
     if isinstance(func, types.FunctionType) and func.func_code.co_flags & CO_VARARGS:
         # calls to *arg functions: create one version per number of args
@@ -121,8 +121,9 @@
 # ____________________________________________________________________________
 # specializations
 
-def memo(bookkeeper, spaceop, func, args, mono):
+def memo(bookkeeper, mod, spaceop, func, args, mono):
     """NOT_RPYTHON"""
+    assert mono, "not-static call to memoized %s" % func
     from pypy.annotation.model import unionof
     # call the function now, and collect possible results
     arglist_s, kwds_s = args.unpack()
@@ -171,7 +172,7 @@
 #        l.append(name)
 #    return func, "__".join(l)
 
-def ctr_location(bookkeeper, spaceop, orig_cls, args, mono):
+def ctr_location(bookkeeper, mod, spaceop, orig_cls, args, mono):
     """NOT_RPYTHON"""
     from pypy.annotation.model import SomeInstance
     v = spaceop.result
@@ -185,14 +186,14 @@
         return cls
 
 def argvalue(i):
-    def specialize_argvalue(bookkeeper, spaceop, func, args, mono):
+    def specialize_argvalue(bookkeeper, mod, spaceop, func, args, mono):
         """NOT_RPYTHON"""
         ignore, args_w = args.flatten()
         return func, args_w[i].const
     return specialize_argvalue
 
 def argtype(i):
-    def specialize_argtype(bookkeeper, spaceop, func, args, mono):
+    def specialize_argtype(bookkeeper, mod, spaceop, func, args, mono):
         """NOT_RPYTHON"""
         ignore, args_w = args.flatten()
         return func, args_w[i].knowntype

Modified: pypy/dist/pypy/translator/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py	(original)
+++ pypy/dist/pypy/translator/annrpython.py	Sun Jun 12 00:34:56 2005
@@ -13,8 +13,6 @@
     pass
 
 class BasicAnnotatorPolicy:
-    def override(pol, func, inputcells):
-        return None
     
     def specialize(pol, bookkeeper, spaceop, func, args, mono):
         return None
@@ -251,9 +249,6 @@
     #___ interface for annotator.bookkeeper _______
 
     def recursivecall(self, func, position_key, inputcells):
-        overriden = self.policy.override(func, inputcells)
-        if overriden is not None:
-            return overriden
         parent_fn, parent_block, parent_index = position_key
         graph = self.getflowgraph(func, parent_fn, position_key)
         # self.notify[graph.returnblock] is a dictionary of call



More information about the Pypy-commit mailing list