[pypy-svn] r14337 - in pypy/dist/pypy/rpython: . test

arigo at codespeak.net arigo at codespeak.net
Wed Jul 6 16:05:02 CEST 2005


Author: arigo
Date: Wed Jul  6 16:04:57 2005
New Revision: 14337

Added:
   pypy/dist/pypy/rpython/rspecialcase.py   (contents, props changed)
   pypy/dist/pypy/rpython/test/test_rspecialcase.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/rclass.py
   pypy/dist/pypy/rpython/rpbc.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/rpython/test/test_llinterp.py
Log:
(arigo, quest)

Handle special-casing of instantiate().
FunctionsPBCRepr only calls getsignature() if needed, to avoid spurious
un-annotated flow graphs for such special-cased functions.

test_llinterp takes a 'policy' argument.



Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py	(original)
+++ pypy/dist/pypy/rpython/rclass.py	Wed Jul  6 16:04:57 2005
@@ -543,10 +543,10 @@
 
 # ____________________________________________________________
 
-def rtype_new_instance(cls, hop):
-    classdef = hop.rtyper.annotator.getuserclasses()[cls]
-    rinstance = getinstancerepr(hop.rtyper, classdef)
-    return rinstance.new_instance(hop.llops)
+def rtype_new_instance(rtyper, cls, llops):
+    classdef = rtyper.annotator.getuserclasses()[cls]
+    rinstance = getinstancerepr(rtyper, classdef)
+    return rinstance.new_instance(llops)
 
 def instance_annotation_for_cls(rtyper, cls):
     try:

Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/rpbc.py	Wed Jul  6 16:04:57 2005
@@ -278,52 +278,42 @@
     def __init__(self, rtyper, s_pbc):
         self.rtyper = rtyper
         self.s_pbc = s_pbc
-        self.function_signatures = {}
-        for func in s_pbc.prebuiltinstances:
-            self.function_signatures[func] = getsignature(rtyper, func)
-
-        if len(self.function_signatures) == 1:
+        self._function_signatures = None
+        if len(s_pbc.prebuiltinstances) == 1:
             # a single function
             self.lowleveltype = Void
         else:
-            signatures = self.function_signatures.values()
+            signatures = self.function_signatures().values()
             sig0 = signatures[0]
             for sig1 in signatures[1:]:
                 assert typeOf(sig0[0]) == typeOf(sig1[0])  # XXX not implemented
                 assert sig0[1:] == sig1[1:]                # XXX not implemented
             self.lowleveltype = typeOf(sig0[0])
 
-##            callfamilies = rtyper.annotator.getpbccallfamilies()
-##            try:
-##                _, _, callfamily = callfamilies[None, functions[0]]
-##            except KeyError:
-##                self.lowleveltype = Void   # no call family found
-##            else:
-##                shapes = callfamily.patterns
-##                assert len(shapes) == 1, "XXX not implemented"
-##                shape, = shapes
-##                shape_cnt, shape_keys, shape_star, shape_stst = shape
-##                assert not shape_keys, "XXX not implemented"
-##                assert not shape_star, "XXX not implemented"
-##                assert not shape_stst, "XXX not implemented"
+    def function_signatures(self):
+        if self._function_signatures is None:
+            self._function_signatures = {}
+            for func in self.s_pbc.prebuiltinstances:
+                self._function_signatures[func] = getsignature(self.rtyper,func)
+        return self._function_signatures
 
     def convert_const(self, value):
         if isinstance(value, types.MethodType) and value.im_self is None:
             value = value.im_func   # unbound method -> bare function
-        if value not in self.function_signatures:
+        if value not in self.function_signatures():
             raise TyperError("%r not in %r" % (value,
                                                self.s_pbc.prebuiltinstances))
-        f, rinputs, rresult = self.function_signatures[value]
+        f, rinputs, rresult = self.function_signatures()[value]
         return f
 
     def rtype_simple_call(self, hop):
-        f, rinputs, rresult = self.function_signatures.itervalues().next()
+        f, rinputs, rresult = self.function_signatures().itervalues().next()
         defaultclist = []
         if len(rinputs) != hop.nb_args-1:  # argument count mismatch
             assert not getattr(f._obj.graph, 'normalized_for_calls', False), (
                 "normalization bug")
-            assert len(self.function_signatures) == 1, "normalization bug too"
-            func, = self.function_signatures.keys()
+            assert len(self.function_signatures()) == 1, "normalization bug too"
+            func, = self.function_signatures().keys()
             defaults = func.func_defaults or ()
             if len(rinputs) - len(defaults) <= hop.nb_args-1 <= len(rinputs):
                 rinputs = list(rinputs)
@@ -338,13 +328,13 @@
                     raise RTyperError("not enough arguments in function call")
         vlist = hop.inputargs(self, *rinputs) + defaultclist
         if self.lowleveltype == Void:
-            assert len(self.function_signatures) == 1
+            assert len(self.function_signatures()) == 1
             vlist[0] = hop.inputconst(typeOf(f), f)
         v = hop.genop('direct_call', vlist, resulttype = rresult)
         return hop.llops.convertvar(v, rresult, hop.r_result)
 
     def rtype_call_args(self, hop):
-        f, rinputs, rresult = self.function_signatures.itervalues().next()
+        f, rinputs, rresult = self.function_signatures().itervalues().next()
         # the function arguments may have been normalized by normalizecalls()
         # already
         if not f._obj.graph.normalized_for_calls:
@@ -453,7 +443,7 @@
 
     def rtype_simple_call(self, hop):
         klass = self.s_pbc.const
-        v_instance = rclass.rtype_new_instance(klass, hop)
+        v_instance = rclass.rtype_new_instance(hop.rtyper, klass, hop.llops)
         try:
             initfunc = klass.__init__.im_func
         except AttributeError:

Added: pypy/dist/pypy/rpython/rspecialcase.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rspecialcase.py	Wed Jul  6 16:04:57 2005
@@ -0,0 +1,32 @@
+from pypy.annotation.pairtype import pairtype
+from pypy.annotation import model as annmodel
+from pypy.objspace.flow.model import Constant
+from pypy.rpython import rclass
+
+
+def rtype_call_specialcase(hop):
+    v_function = hop.args_v[0]
+    if not isinstance(v_function, Constant):
+        raise TyperError("call_specialcase on a variable function")
+    func = v_function.value
+    tag = func._annspecialcase_
+    if not tag.startswith("override:"):
+        raise TyperError("call_specialcase only supports 'override:' functions")
+    tag = tag[9:]
+    try:
+        rtype_override_fn = globals()['rtype_override_' + tag]
+    except KeyError:
+        raise TyperError("call_specialcase: unknown tag override:" + tag)
+    hop2 = hop.copy()
+    hop2.r_s_popfirstarg()
+    return rtype_override_fn(hop2)
+
+
+def rtype_override_instantiate(hop):
+    s_class = hop.args_s[0]
+    assert isinstance(s_class, annmodel.SomePBC)
+    if len(s_class.prebuiltinstances) != 1:
+        raise TyperError("instantiate() on a variable class")
+
+    klass = s_class.const
+    return rclass.rtype_new_instance(hop.rtyper, klass, hop.llops)

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Wed Jul  6 16:04:57 2005
@@ -351,6 +351,9 @@
     def translate_op_call_memo(self, hop):
         return rpbc.rtype_call_memo(hop)
 
+    def translate_op_call_specialcase(self, hop):
+        return rspecialcase.rtype_call_specialcase(hop)
+
     def missing_operation(self, hop):
         raise TyperError("unimplemented operation: '%s'" % hop.spaceop.opname)
 
@@ -541,7 +544,7 @@
 from pypy.rpython import rint, rbool, rfloat
 from pypy.rpython import rslice
 from pypy.rpython import rlist, rstr, rtuple, rdict 
-from pypy.rpython import rclass, rbuiltin, rpbc
+from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
 from pypy.rpython import rptr
 
 RPythonTyper.fixednames = {}

Modified: pypy/dist/pypy/rpython/test/test_llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llinterp.py	(original)
+++ pypy/dist/pypy/rpython/test/test_llinterp.py	Wed Jul  6 16:04:57 2005
@@ -27,19 +27,19 @@
             if func(pyobjectptr(cls)).typeptr == klass:
                 return cls
 
-def timelog(prefix, call, *args): 
+def timelog(prefix, call, *args, **kwds): 
     #import time
     #print prefix, "...", 
     #start = time.time()
-    res = call(*args) 
+    res = call(*args, **kwds) 
     #elapsed = time.time() - start 
     #print "%.2f secs" %(elapsed,)
     return res 
 
-def gengraph(func, argtypes=[], viewbefore=False):
+def gengraph(func, argtypes=[], viewbefore=False, policy=None):
     t = Translator(func)
 
-    timelog("annotating", t.annotate, argtypes)
+    timelog("annotating", t.annotate, argtypes, policy=policy)
     if viewbefore:
         t.annotator.simplify()
         t.view()
@@ -52,13 +52,13 @@
 
 _lastinterpreted = []
 _tcache = {}
-def interpret(func, values, view=False, viewbefore=False):
+def interpret(func, values, view=False, viewbefore=False, policy=None):
     key = (func,) + tuple([typeOf(x) for x in values])
     try: 
         (t, interp) = _tcache[key]
     except KeyError: 
         t, typer = gengraph(func, [lltype_to_annotation(typeOf(x)) 
-                      for x in values], viewbefore)
+                      for x in values], viewbefore, policy)
         interp = LLInterpreter(t.flowgraphs, typer)
         _tcache[key] = (t, interp)
         # keep the cache small 

Added: pypy/dist/pypy/rpython/test/test_rspecialcase.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_rspecialcase.py	Wed Jul  6 16:04:57 2005
@@ -0,0 +1,14 @@
+from pypy.rpython.lltype import *
+from pypy.rpython.test.test_llinterp import interpret
+
+from pypy.translator.ann_override import PyPyAnnotatorPolicy
+from pypy.interpreter.typedef import instantiate
+
+
+def test_instantiate():
+    class A:
+        pass
+    def f():
+        return instantiate(A)
+    res = interpret(f, [], policy=PyPyAnnotatorPolicy())
+    assert res.super.typeptr.name[0] == 'A'



More information about the Pypy-commit mailing list