[pypy-svn] r26349 - in pypy/dist/pypy: objspace/cpy objspace/cpy/test translator/goal
arigo at codespeak.net
arigo at codespeak.net
Wed Apr 26 09:51:28 CEST 2006
Author: arigo
Date: Wed Apr 26 09:51:25 2006
New Revision: 26349
Modified:
pypy/dist/pypy/objspace/cpy/ann_policy.py
pypy/dist/pypy/objspace/cpy/capi.py
pypy/dist/pypy/objspace/cpy/objspace.py
pypy/dist/pypy/objspace/cpy/test/test_compile.py
pypy/dist/pypy/objspace/cpy/wrappable.py
pypy/dist/pypy/translator/goal/targetdemomodule.py
Log:
* "fastest blinking code of the week": removed the TrampolineEntry
extregistry hacks for the second time. Found a robust approach
to annotate all the generated trampoline functions.
* more CPyObjSpace operations
Modified: pypy/dist/pypy/objspace/cpy/ann_policy.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/ann_policy.py (original)
+++ pypy/dist/pypy/objspace/cpy/ann_policy.py Wed Apr 26 09:51:25 2006
@@ -1,6 +1,28 @@
from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy
+from pypy.annotation.pairtype import pair
class CPyAnnotatorPolicy(PyPyAnnotatorPolicy):
"""Annotation policy to compile CPython extension modules with
the CPyObjSpace.
"""
+
+ def __init__(self, space):
+ PyPyAnnotatorPolicy.__init__(self, single_space=space)
+ self.spaces = {}
+
+ def no_more_blocks_to_annotate(self, annotator):
+ PyPyAnnotatorPolicy.no_more_blocks_to_annotate(self, annotator)
+
+ # annotate all indirectly reachable call-back functions
+ space = self.single_space
+ pending = {}
+ while True:
+ nb_done = len(pending)
+ pending.update(space.wrap_cache)
+ if len(pending) == nb_done:
+ break
+ for obj, w_obj in pending.items():
+ pair(space, obj).follow_annotations(annotator.bookkeeper,
+ w_obj)
+ # restart this loop: for all we know follow_annotations()
+ # could have found new objects
Modified: pypy/dist/pypy/objspace/cpy/capi.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/capi.py (original)
+++ pypy/dist/pypy/objspace/cpy/capi.py Wed Apr 26 09:51:25 2006
@@ -82,6 +82,14 @@
PyObject_RichCompareBool.argtypes = [W_Object, W_Object, c_int]
PyObject_RichCompareBool.restype = c_int
+PyObject_GetIter = pythonapi.PyObject_GetIter
+PyObject_GetIter.argtypes = [W_Object]
+PyObject_GetIter.restype = W_Object
+
+PyIter_Next = pythonapi.PyIter_Next
+PyIter_Next.argtypes = [W_Object]
+PyIter_Next.restype = W_Object
+
#############################################################
# ____________________ Sequence Protocol ____________________
@@ -118,6 +126,10 @@
PyString_InternInPlace.argtypes = [POINTER(W_Object)]
PyString_InternInPlace.restype = None
+PyString_AsString = pythonapi.PyString_AsString
+PyString_AsString.argtypes = [W_Object]
+PyString_AsString.restype = c_char_p
+
##################################################
# ____________________ Tuples ____________________
Modified: pypy/dist/pypy/objspace/cpy/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/objspace.py (original)
+++ pypy/dist/pypy/objspace/cpy/objspace.py Wed Apr 26 09:51:25 2006
@@ -1,24 +1,26 @@
from pypy.objspace.cpy.capi import *
from pypy.annotation.pairtype import pair
from pypy.interpreter import baseobjspace
+from pypy.interpreter.error import OperationError
-class CPyObjSpace:
+class CPyObjSpace(baseobjspace.ObjSpace):
from pypy.objspace.cpy.capi import W_Object
- def __init__(self):
- self.fromcache = baseobjspace.InternalSpaceCache(self).getorbuild
+ def initialize(self):
+ self.options.geninterp = True
self.w_int = W_Object(int)
self.w_None = W_Object(None)
self.w_False = W_Object(False)
self.w_True = W_Object(True)
+ self.w_type = W_Object(type)
+ self.w_Exception = W_Object(Exception)
+ self.w_StopIteration = W_Object(StopIteration)
self.wrap_cache = {}
+ self.rev_wrap_cache = {}
- def enter_cache_building_mode(self):
- pass
-
- def leave_cache_building_mode(self, val):
- pass
+ def _freeze_(self):
+ return True
def getbuiltinmodule(self, name):
return PyImport_ImportModule(name)
@@ -33,6 +35,7 @@
import pypy.objspace.cpy.wrappable
result = pair(self, x).wrap()
self.wrap_cache[x] = result
+ self.rev_wrap_cache[id(result)] = result, x
return result
if x is None:
return self.w_None
@@ -47,23 +50,46 @@
assert isinstance(w_obj, W_Object)
return w_obj.value
+ def finditem(self, w_obj, w_key):
+ try:
+ return self.getitem(w_obj, w_key)
+ except KeyError: # XXX think about OperationError
+ return None
+
+ def interpclass_w(self, w_obj):
+ try:
+ return self.rev_wrap_cache[id(w_obj)][1]
+ except KeyError:
+ return None
+
+ # __________ operations with a direct CPython equivalent __________
+
getattr = staticmethod(PyObject_GetAttr)
getitem = staticmethod(PyObject_GetItem)
setitem = staticmethod(PyObject_SetItem)
int_w = staticmethod(PyInt_AsLong)
+ str_w = staticmethod(PyString_AsString)
+ iter = staticmethod(PyObject_GetIter)
def call_function(self, w_callable, *args_w):
args_w += (None,)
return PyObject_CallFunctionObjArgs(w_callable, *args_w)
- def _freeze_(self):
- return True
+ def call_args(self, w_callable, args):
+ args_w, kwds_w = args.unpack()
+ w_args = self.newtuple(args_w)
+ w_kwds = self.newdict([(self.wrap(key), w_value)
+ for key, w_value in kwds_w.items()])
+ return PyObject_Call(w_callable, w_args, w_kwds)
def new_interned_str(self, s):
w_s = self.wrap(s)
PyString_InternInPlace(byref(w_s))
return w_s
+ def newint(self, intval):
+ return PyInt_FromLong(intval)
+
def newdict(self, items_w):
w_dict = PyDict_New()
for w_key, w_value in items_w:
@@ -97,3 +123,16 @@
def ne_w(self, w1, w2): return PyObject_RichCompareBool(w1, w2, Py_NE) != 0
def gt_w(self, w1, w2): return PyObject_RichCompareBool(w1, w2, Py_GT) != 0
def ge_w(self, w1, w2): return PyObject_RichCompareBool(w1, w2, Py_GE) != 0
+
+ def is_w(self, w1, w2):
+ return w1.value is w2.value # XXX any idea not involving SomeObjects?
+ is_w.allow_someobjects = True
+
+ def is_(self, w1, w2):
+ return self.newbool(self.is_w(w1, w2))
+
+ def next(self, w_obj):
+ w_res = PyIter_Next(w_obj)
+ if not w_res:
+ raise OperationError(self.w_StopIteration, self.w_None)
+ return w_res
Modified: pypy/dist/pypy/objspace/cpy/test/test_compile.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/test/test_compile.py (original)
+++ pypy/dist/pypy/objspace/cpy/test/test_compile.py Wed Apr 26 09:51:25 2006
@@ -18,7 +18,7 @@
return demo.measuretime(space, n, w_callable)
fn = compile(entry_point, [int, CPyObjSpace.W_Object],
- annotatorpolicy = CPyAnnotatorPolicy())
+ annotatorpolicy = CPyAnnotatorPolicy(space))
res = fn(10, long)
assert isinstance(res, int)
@@ -39,12 +39,12 @@
def entrypoint(n):
w_result = space.call_function(w_myfunc, space.wrap(n))
return space.int_w(w_result)
- return entrypoint
+ return space, entrypoint
def test_annotate_bltinfunc():
- entrypoint = maketest()
+ space, entrypoint = maketest()
t = TranslationContext()
- a = t.buildannotator(policy=CPyAnnotatorPolicy())
+ a = t.buildannotator(policy=CPyAnnotatorPolicy(space))
s = a.build_types(entrypoint, [int])
if conftest.option.view:
t.view()
@@ -56,10 +56,31 @@
s = a.binding(graph.getreturnvar())
assert s.knowntype == CPyObjSpace.W_Object
+def test_annotate_indirect():
+ space = CPyObjSpace()
+ func = interp2app(myfunc).__spacebind__(space)
+ bltin = BuiltinFunction(func)
+ w_myfunc = space.wrap(bltin)
+ w_mylist = space.newlist([w_myfunc])
+ def entrypoint():
+ return w_mylist
+ t = TranslationContext()
+ a = t.buildannotator(policy=CPyAnnotatorPolicy(space))
+ s = a.build_types(entrypoint, [])
+ if conftest.option.view:
+ t.view()
+ # 'myfunc' should still have been annotated
+ graph = graphof(t, myfunc)
+ assert len(graph.getargs()) == 2
+ s = a.binding(graph.getargs()[1])
+ assert s.knowntype == CPyObjSpace.W_Object
+ s = a.binding(graph.getreturnvar())
+ assert s.knowntype == CPyObjSpace.W_Object
+
def test_compile_bltinfunc():
- entrypoint = maketest()
+ space, entrypoint = maketest()
fn = compile(entrypoint, [int],
- annotatorpolicy = CPyAnnotatorPolicy())
+ annotatorpolicy = CPyAnnotatorPolicy(space))
res = fn(-6)
assert res == -42
@@ -75,11 +96,11 @@
w_result = space.call_function(w_measuretime, space.wrap(n),
w_callable)
return space.int_w(w_result)
- return entrypoint
+ return space, entrypoint
def test_compile_demo():
- entrypoint = makedemotest()
+ space, entrypoint = makedemotest()
fn = compile(entrypoint, [int, CPyObjSpace.W_Object],
- annotatorpolicy = CPyAnnotatorPolicy())
+ annotatorpolicy = CPyAnnotatorPolicy(space))
res = fn(10, complex)
assert isinstance(res, int)
Modified: pypy/dist/pypy/objspace/cpy/wrappable.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/wrappable.py (original)
+++ pypy/dist/pypy/objspace/cpy/wrappable.py Wed Apr 26 09:51:25 2006
@@ -7,10 +7,9 @@
from pypy.annotation.pairtype import pair, pairtype
from pypy.objspace.cpy.capi import *
from pypy.objspace.cpy.objspace import CPyObjSpace
-from pypy.interpreter.function import BuiltinFunction
+from pypy.interpreter.function import Function
from pypy.interpreter.gateway import BuiltinCode, ObjSpace, W_Root
from pypy.interpreter.gateway import UnwrapSpecRecipe, Signature
-from pypy.rpython import extregistry
class UnwrapSpec_Trampoline(UnwrapSpecRecipe):
@@ -50,11 +49,11 @@
self.passedargs = []
-class __extend__(pairtype(CPyObjSpace, BuiltinFunction)):
+class __extend__(pairtype(CPyObjSpace, Function)):
def wrap((space, func)):
# make a built-in function
- assert isinstance(func.code, BuiltinCode)
+ assert isinstance(func.code, BuiltinCode) # XXX
factory = func.code.framefactory
bltin = factory.behavior
unwrap_spec = factory.unwrap_spec
@@ -87,28 +86,14 @@
exec py.code.Source('\n'.join(sourcelines)).compile() in miniglobals
trampoline = miniglobals['trampoline']
+ trampoline.nb_args = len(tramp.inputargs)
trampoline.allow_someobjects = True # annotator hint
- w_result = W_Object(trampoline)
+ return W_Object(trampoline)
- # override the annotation behavior of 'w_result'
- # to emulate a call to the trampoline() function at interp-level
- BaseEntry = extregistry._lookup_cls(w_result)
+ def follow_annotations((space, func), bookkeeper, w_trampoline):
+ from pypy.annotation import model as annmodel
+ trampoline = w_trampoline.value
+ s_trampoline = bookkeeper.immutablevalue(trampoline)
+ args_s = [annmodel.SomeObject()] * trampoline.nb_args
uniquekey = trampoline
- nb_args = len(unwrap_spec) - 1
-
- class TrampolineEntry(BaseEntry):
- _about_ = w_result
-
- def compute_annotation(self):
- from pypy.annotation import model as annmodel
- from pypy.annotation.bookkeeper import getbookkeeper
-
- bookkeeper = getbookkeeper()
- if bookkeeper is not None: # else probably already rtyping
- s_trampoline = bookkeeper.immutablevalue(trampoline)
- args_s = [annmodel.SomeObject()]*nb_args
- bookkeeper.emulate_pbc_call(uniquekey, s_trampoline,
- args_s)
- return super(TrampolineEntry, self).compute_annotation()
-
- return w_result
+ bookkeeper.emulate_pbc_call(uniquekey, s_trampoline, args_s)
Modified: pypy/dist/pypy/translator/goal/targetdemomodule.py
==============================================================================
--- pypy/dist/pypy/translator/goal/targetdemomodule.py (original)
+++ pypy/dist/pypy/translator/goal/targetdemomodule.py Wed Apr 26 09:51:25 2006
@@ -1,18 +1,21 @@
-from pypy.module._demo import demo
+from pypy.module._demo import Module, demo
from pypy.objspace.cpy.ann_policy import CPyAnnotatorPolicy
from pypy.objspace.cpy.objspace import CPyObjSpace
import pypy.rpython.rctypes.implementation
space = CPyObjSpace()
+Module.appleveldefs.clear() # XXX! for now
+module = Module(space, space.wrap('_demo'))
+w_moduledict = module.getdict()
-def entry_point(n, w_callable):
- return demo.measuretime(space, n, w_callable)
+def getdict():
+ return w_moduledict
# _____ Define and setup target ___
def target(*args):
- return entry_point, [int, CPyObjSpace.W_Object], CPyAnnotatorPolicy()
+ return getdict, [], CPyAnnotatorPolicy(space)
if __name__ == '__main__':
@@ -22,4 +25,4 @@
else:
N = int(sys.argv[1])
print 'Timing for %d iterations...' % N
- print entry_point(N, space.W_Object(int)), 'seconds'
+ print demo.measuretime(space, N, space.W_Object(int)), 'seconds'
More information about the Pypy-commit
mailing list