[pypy-svn] r23881 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem test
nik at codespeak.net
nik at codespeak.net
Thu Mar 2 01:02:08 CET 2006
Author: nik
Date: Thu Mar 2 01:02:04 2006
New Revision: 23881
Modified:
pypy/dist/pypy/rpython/lltypesystem/rpbc.py
pypy/dist/pypy/rpython/ootypesystem/rpbc.py
pypy/dist/pypy/rpython/rpbc.py
pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
(pedronis, nik)
made specialized functions work for ootype by factoring out an abstract
FunctionsPBCRepr. fixed a test about frozen methods that wasn't testing
what it thought it was (no _freeze_ method!). discovered by accident
a different failing tests for specialized methods with ootype, disabled
for now.
Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Thu Mar 2 01:02:04 2006
@@ -11,9 +11,10 @@
from pypy.rpython import robject
from pypy.rpython import rtuple
from pypy.rpython.rpbc import samesig,\
- commonbase, allattributenames, adjust_shape, FunctionsPBCRepr, \
+ commonbase, allattributenames, adjust_shape, \
AbstractClassesPBCRepr, AbstractMethodsPBCRepr, OverriddenFunctionPBCRepr, \
- AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr
+ AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
+ AbstractFunctionsPBCRepr
from pypy.rpython.lltypesystem import rclass
from pypy.tool.sourcetools import has_varargs
@@ -54,6 +55,21 @@
# ____________________________________________________________
+class FunctionsPBCRepr(AbstractFunctionsPBCRepr):
+ """Representation selected for a PBC of function(s)."""
+
+ def setup_specfunc(self):
+ fields = []
+ for row in self.uniquerows:
+ fields.append((row.attrname, row.fntype))
+ return Ptr(Struct('specfunc', *fields))
+
+ def create_specfunc(self):
+ return malloc(self.lowleveltype.TO, immortal=True)
+
+ def get_specfunc_row(self, llop, v, c_rowname, resulttype):
+ return llop.genop('getfield', [v, c_rowname], resulttype=resulttype)
+
class MethodsPBCRepr(AbstractMethodsPBCRepr):
"""Representation selected for a PBC of the form {func: classdef...}.
It assumes that all the methods come from the same name in a base
Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Thu Mar 2 01:02:04 2006
@@ -1,6 +1,7 @@
from pypy.rpython.rmodel import CanBeNull, Repr, inputconst
from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr, \
- AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr
+ AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
+ AbstractFunctionsPBCRepr
from pypy.rpython.rclass import rtype_new_instance, getinstancerepr
from pypy.rpython.rpbc import get_concrete_calltable
from pypy.rpython import callparse
@@ -12,6 +13,22 @@
from pypy.annotation.pairtype import pairtype
import types
+
+class FunctionsPBCRepr(AbstractFunctionsPBCRepr):
+ """Representation selected for a PBC of function(s)."""
+
+ def setup_specfunc(self):
+ fields = {}
+ for row in self.uniquerows:
+ fields[row.attrname] = row.fntype
+ return ootype.Instance('specfunc', ootype.ROOT, fields)
+
+ def create_specfunc(self):
+ return ootype.new(self.lowleveltype)
+
+ def get_specfunc_row(self, llop, v, c_rowname, resulttype):
+ return llop.genop('oogetfield', [v, c_rowname], resulttype=resulttype)
+
class ClassesPBCRepr(AbstractClassesPBCRepr):
def rtype_simple_call(self, hop):
Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py (original)
+++ pypy/dist/pypy/rpython/rpbc.py Thu Mar 2 01:02:04 2006
@@ -26,7 +26,7 @@
if sample.overridden:
getRepr = OverriddenFunctionPBCRepr
else:
- getRepr = FunctionsPBCRepr
+ getRepr = rtyper.type_system.rpbc.FunctionsPBCRepr
else:
getRepr = getFrozenPBCRepr
elif issubclass(kind, description.ClassDesc):
@@ -155,7 +155,7 @@
return concretetable, uniquerows
-class FunctionsPBCRepr(CanBeNull, Repr):
+class AbstractFunctionsPBCRepr(CanBeNull, Repr):
"""Representation selected for a PBC of function(s)."""
def __init__(self, rtyper, s_pbc):
@@ -177,10 +177,7 @@
# several functions, each with several specialized variants.
# each function becomes a pointer to a Struct containing
# pointers to its variants.
- fields = []
- for row in uniquerows:
- fields.append((row.attrname, row.fntype))
- self.lowleveltype = Ptr(Struct('specfunc', *fields))
+ self.lowleveltype = self.setup_specfunc()
self.funccache = {}
def get_s_callable(self):
@@ -230,7 +227,7 @@
result = llfn # from the loop above
else:
# build a Struct with all the values collected in 'llfns'
- result = malloc(self.lowleveltype.TO, immortal=True)
+ result = self.create_specfunc()
for attrname, llfn in llfns.items():
setattr(result, attrname, llfn)
self.funccache[funcdesc] = result
@@ -267,7 +264,7 @@
# 'v' is a Struct pointer, read the corresponding field
row = self.concretetable[shape, index]
cname = inputconst(Void, row.attrname)
- return llop.genop('getfield', [v, cname], resulttype = row.fntype)
+ return self.get_specfunc_row(llop, v, cname, row.fntype)
def get_unique_llfn(self):
# try to build a unique low-level function. Avoid to use
@@ -320,7 +317,7 @@
v = hop.genop('indirect_call', vlist, resulttype = rresult)
return hop.llops.convertvar(v, rresult, hop.r_result)
-class __extend__(pairtype(FunctionsPBCRepr, FunctionsPBCRepr)):
+class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractFunctionsPBCRepr)):
def convert_from_to((r_fpbc1, r_fpbc2), v, llops):
# this check makes sense because both source and dest repr are FunctionsPBCRepr
if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype:
Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py (original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py Thu Mar 2 01:02:04 2006
@@ -967,54 +967,81 @@
assert res.item0 == f(i)[0]
assert res.item1 == f(i)[1]
-def test_multiple_specialized_functions():
- def myadder(x, y): # int,int->int or str,str->str
- return x+y
- def myfirst(x, y): # int,int->int or str,str->str
- return x
- def mysecond(x, y): # int,int->int or str,str->str
- return y
- myadder._annspecialcase_ = 'specialize:argtype(0)'
- myfirst._annspecialcase_ = 'specialize:argtype(0)'
- mysecond._annspecialcase_ = 'specialize:argtype(0)'
- def f(i):
- if i == 0:
- g = myfirst
- elif i == 1:
- g = mysecond
- else:
- g = myadder
- s = g("hel", "lo")
- n = g(40, 2)
- return len(s) * n
- for i in range(3):
- res = interpret(f, [i])
- assert res == f(i)
-
-def test_specialized_method_of_frozen():
- class space:
- def __init__(self, tag):
- self.tag = tag
- def wrap(self, x):
- if isinstance(x, int):
- return self.tag + '< %d >' % x
+ def test_multiple_specialized_functions(self):
+ def myadder(x, y): # int,int->int or str,str->str
+ return x+y
+ def myfirst(x, y): # int,int->int or str,str->str
+ return x
+ def mysecond(x, y): # int,int->int or str,str->str
+ return y
+ myadder._annspecialcase_ = 'specialize:argtype(0)'
+ myfirst._annspecialcase_ = 'specialize:argtype(0)'
+ mysecond._annspecialcase_ = 'specialize:argtype(0)'
+ def f(i):
+ if i == 0:
+ g = myfirst
+ elif i == 1:
+ g = mysecond
else:
- return self.tag + x
- wrap._annspecialcase_ = 'specialize:argtype(1)'
- space1 = space("tag1:")
- space2 = space("tag2:")
- def f(i):
- if i == 1:
- sp = space1
- else:
- sp = space2
- w1 = sp.wrap('hello')
- w2 = sp.wrap(42)
- return w1 + w2
- res = interpret(f, [1])
- assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >'
- res = interpret(f, [0])
- assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >'
+ g = myadder
+ s = g("hel", "lo")
+ n = g(40, 2)
+ return len(s) * n
+ for i in range(3):
+ res = interpret(f, [i], type_system=self.ts)
+ assert res == f(i)
+
+ def test_specialized_method_of_frozen(self):
+ class space:
+ def _freeze_(self):
+ return True
+ def __init__(self, tag):
+ self.tag = tag
+ def wrap(self, x):
+ if isinstance(x, int):
+ return self.tag + '< %d >' % x
+ else:
+ return self.tag + x
+ wrap._annspecialcase_ = 'specialize:argtype(1)'
+ space1 = space("tag1:")
+ space2 = space("tag2:")
+ def f(i):
+ if i == 1:
+ sp = space1
+ else:
+ sp = space2
+ w1 = sp.wrap('hello')
+ w2 = sp.wrap(42)
+ return w1 + w2
+ res = interpret(f, [1], type_system=self.ts)
+ assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >'
+ res = interpret(f, [0], type_system=self.ts)
+ assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >'
+
+ def DONT_test_specialized_method(self):
+ class A:
+ def __init__(self, tag):
+ self.tag = tag
+ def wrap(self, x):
+ if isinstance(x, int):
+ return self.tag + '< %d >' % x
+ else:
+ return self.tag + x
+ wrap._annspecialcase_ = 'specialize:argtype(1)'
+ a1 = A("tag1:")
+ a2 = A("tag2:")
+ def f(i):
+ if i == 1:
+ sp = a1
+ else:
+ sp = a2
+ w1 = sp.wrap('hello')
+ w2 = sp.wrap(42)
+ return w1 + w2
+ res = interpret(f, [1], type_system=self.ts)
+ assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >'
+ res = interpret(f, [0], type_system=self.ts)
+ assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >'
def test_call_from_list():
def f0(n): return n+200
More information about the Pypy-commit
mailing list