[pypy-svn] r14307 - in pypy/branch/dist-2.4.1/pypy: annotation interpreter interpreter/pyparser module/recparser objspace/std objspace/std/test rpython rpython/test translator/c translator/c/test translator/llvm2 translator/llvm2/test
arigo at codespeak.net
arigo at codespeak.net
Tue Jul 5 20:13:27 CEST 2005
Author: arigo
Date: Tue Jul 5 20:13:26 2005
New Revision: 14307
Added:
pypy/branch/dist-2.4.1/pypy/rpython/extfunctable.py
- copied unchanged from r14306, pypy/dist/pypy/rpython/extfunctable.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/varsize.py
- copied unchanged from r14306, pypy/dist/pypy/translator/llvm2/varsize.py
Modified:
pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py
pypy/branch/dist-2.4.1/pypy/annotation/builtin.py
pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py
pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py
pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py
pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py
pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py
pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py
pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py
pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py
pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py
pypy/branch/dist-2.4.1/pypy/rpython/rstr.py
pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py
pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py
pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py
pypy/branch/dist-2.4.1/pypy/translator/c/database.py
pypy/branch/dist-2.4.1/pypy/translator/c/node.py
pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py
pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py
Log:
svn merge -r14266:14306 http://codespeak.net/svn/pypy/dist
Modified: pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py (original)
+++ pypy/branch/dist-2.4.1/pypy/annotation/bookkeeper.py Tue Jul 5 20:13:26 2005
@@ -627,7 +627,7 @@
raise Exception, "no __init__ found in %r" % (cls,)
return s_instance
- assert isinstance(func, FunctionType), "[%s] expected function, got %r" % (self.whereami(), func)
+ assert isinstance(func, FunctionType), "[%s] expected user-defined function, got %r" % (self.whereami(), func)
inputcells = self.get_inputcells(func, args)
Modified: pypy/branch/dist-2.4.1/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/annotation/builtin.py (original)
+++ pypy/branch/dist-2.4.1/pypy/annotation/builtin.py Tue Jul 5 20:13:26 2005
@@ -67,9 +67,8 @@
return constpropagate(bool, [s_obj], SomeBool())
def builtin_int(s_obj, s_base=None):
- assert (s_base is None or s_base.is_constant()
- and s_base.const == 16
- and s_obj.knowntype == str), "only int(v|string) or int(string,16) expected"
+ assert (s_base is None or isinstance(s_base, SomeInteger)
+ and s_obj.knowntype == str), "only int(v|string) or int(string,int) expected"
if s_base is not None:
args_s = [s_obj, s_base]
else:
@@ -336,3 +335,9 @@
BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
+from pypy.rpython import extfunctable
+
+# import annotation information for external functions
+# from the extfunctable.table into our own annotation specific table
+for func, extfuncinfo in extfunctable.table.iteritems():
+ BUILTIN_ANALYZERS[func] = extfuncinfo.annotation
Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py (original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyopcode.py Tue Jul 5 20:13:26 2005
@@ -171,6 +171,7 @@
BINARY_TRUE_DIVIDE = binaryoperation("truediv")
BINARY_FLOOR_DIVIDE = binaryoperation("floordiv")
BINARY_DIVIDE = binaryoperation("div")
+ # XXX BINARY_DIVIDE must fall back to BINARY_TRUE_DIVIDE with -Qnew
BINARY_MODULO = binaryoperation("mod")
BINARY_ADD = binaryoperation("add")
BINARY_SUBTRACT = binaryoperation("sub")
@@ -191,6 +192,7 @@
INPLACE_TRUE_DIVIDE = binaryoperation("inplace_truediv")
INPLACE_FLOOR_DIVIDE = binaryoperation("inplace_floordiv")
INPLACE_DIVIDE = binaryoperation("inplace_div")
+ # XXX INPLACE_DIVIDE must fall back to INPLACE_TRUE_DIVIDE with -Qnew
INPLACE_MODULO = binaryoperation("inplace_mod")
INPLACE_ADD = binaryoperation("inplace_add")
INPLACE_SUBTRACT = binaryoperation("inplace_sub")
Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py (original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py Tue Jul 5 20:13:26 2005
@@ -1,5 +1,4 @@
-__all__ = ["python_parse", "pypy_parse", "ast_single_input", "ast_file_input",
- "ast_eval_input"]
+__all__ = ["python_parse", "pypy_parse"]
import parser
import symbol
Modified: pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py (original)
+++ pypy/branch/dist-2.4.1/pypy/module/recparser/pyparser.py Tue Jul 5 20:13:26 2005
@@ -8,7 +8,6 @@
from pypy.interpreter.typedef import interp_attrproperty, GetSetProperty
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.pyparser.syntaxtree import SyntaxNode
-from pypy.interpreter.pyparser.pythonparse import parse_python_source
from pypy.interpreter.pyparser.pythonutil import PYTHON_PARSER
__all__ = [ "ASTType", "STType", "suite", "expr" ]
@@ -101,16 +100,14 @@
def suite( space, source ):
# make the annotator life easier (don't use str.splitlines())
- strings = [line + '\n' for line in source.split('\n')]
- builder = parse_python_source( strings, PYTHON_PARSER, "file_input" )
+ builder = PYTHON_PARSER.parse_source( source, "file_input" )
return space.wrap( STType(space, builder.stack[-1]) )
suite.unwrap_spec = [ObjSpace, str]
def expr( space, source ):
# make the annotator life easier (don't use str.splitlines())
- strings = [line + '\n' for line in source.split('\n')]
- builder = parse_python_source( strings, PYTHON_PARSER, "eval_input" )
+ builder = PYTHON_PARSER.parse_source( source, "eval_input" )
return space.wrap( STType(space, builder.stack[-1]) )
expr.unwrap_spec = [ObjSpace, str]
Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py (original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/intobject.py Tue Jul 5 20:13:26 2005
@@ -209,13 +209,8 @@
m = x % y
return space.wrap((z,m))
-old_style_div = 1 / 2 == 1 // 2
def div__Int_Int(space, w_int1, w_int2):
- # Select the proper div
- if old_style_div:
- return _floordiv(space, w_int1, w_int2)
- else:
- return _truediv(space, w_int1, w_int2)
+ return _floordiv(space, w_int1, w_int2)
floordiv__Int_Int = _floordiv
truediv__Int_Int = _truediv
Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py (original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py Tue Jul 5 20:13:26 2005
@@ -9,7 +9,7 @@
import math
SHORT_BIT = int(LONG_BIT // 2)
-SHORT_MASK = int(LONG_MASK >> SHORT_BIT)
+SHORT_MASK = int((1 << SHORT_BIT) - 1)
SIGN_BIT = LONG_BIT-1
SIGN_MASK = r_uint(1) << SIGN_BIT
@@ -63,7 +63,8 @@
def _setshort(self, index, short):
a = self.digits[index // 2]
- assert isinstance(short, r_uint)
+ ##!!assert isinstance(short, r_uint)
+ assert short & SHORT_MASK == short
if index % 2 == 0:
self.digits[index // 2] = ((a >> SHORT_BIT) << SHORT_BIT) + short
else:
@@ -258,25 +259,19 @@
return space.newfloat(div)
def floordiv__Long_Long(space, w_long1, w_long2):
- div, rem = _divrem(space, w_long1, w_long2)
+ div, mod = _l_divmod(space, w_long1, w_long2)
return div
-old_style_div = 1 / 2 == 1 // 2
def div__Long_Long(space, w_long1, w_long2):
- # Select the proper div
- if old_style_div:
- return floordiv__Long_Long(space, w_long1, w_long2)
- else:
- return truediv__Long_Long(space, w_long1, w_long2)
-
+ return floordiv__Long_Long(space, w_long1, w_long2)
def mod__Long_Long(space, w_long1, w_long2):
- div, rem = _divrem(space, w_long1, w_long2)
- return rem
+ div, mod = _l_divmod(space, w_long1, w_long2)
+ return mod
def divmod__Long_Long(space, w_long1, w_long2):
- div, rem = _divrem(space, w_long1, w_long2)
- return space.newtuple([div, rem])
+ div, mod = _l_divmod(space, w_long1, w_long2)
+ return space.newtuple([div, mod])
# helper for pow() #YYYYYY: still needs longval if second argument is negative
def _impl_long_long_pow(space, lv, lw, lz=None):
@@ -733,6 +728,15 @@
res >>= n
return res
+ def __ilshift__(self, n):
+ self.value <<= n
+ return self
+
+ def __lshift__(self, n):
+ res = r_suint(self)
+ res <<= n
+ return res
+
def __and__(self, mask):
# only used to get bits from the value
return self.value & mask
@@ -742,7 +746,7 @@
other = r_suint(other)
return self.sign == other.sign and self.value == other.value
-def _x_divrem(space, v1, w1): # return as tuple, PyLongObject **prem)
+def _x_divrem(space, v1, w1):
size_w = len(w1.digits) * 2
# hack for the moment:
# find where w1 is really nonzero
@@ -762,8 +766,10 @@
size_a = size_v - size_w + 1
digitpairs = (size_a + 1) // 2
a = W_LongObject(space, [r_uint(0)] * digitpairs, 1)
+
j = size_v
- for k in range(size_a-1, -1, -1):
+ k = size_a - 1
+ while k >= 0:
if j >= size_v:
vj = r_uint(0)
else:
@@ -775,18 +781,20 @@
else:
q = ((vj << SHORT_BIT) + v._getshort(j-1)) // w._getshort(size_w-1)
+ # notabene!
+ # this check needs a signed two digits result
+ # or we get an overflow.
while (w._getshort(size_w-2) * q >
((
- (vj << SHORT_BIT)
+ r_suint(vj << SHORT_BIT) # this one dominates
+ v._getshort(j-1)
- q * w._getshort(size_w-1)
) << SHORT_BIT)
+ v._getshort(j-2)):
q -= 1
- for i in range(size_w):
- if i+k >= size_v:
- break
+ i = 0
+ while i < size_w and i+k < size_v:
z = w._getshort(i) * q
zz = z >> SHORT_BIT
carry += v._getshort(i+k) + (zz << SHORT_BIT)
@@ -794,8 +802,8 @@
v._setshort(i+k, r_uint(carry.value & SHORT_MASK))
carry >>= SHORT_BIT
carry -= zz
+ i += 1
- i += 1 # compare C code which re-uses i of loop
if i+k < size_v:
carry += v._getshort(i+k)
v._setshort(i+k, r_uint(0))
@@ -803,18 +811,18 @@
if carry == 0:
a._setshort(k, q)
else:
- #assert carry == -1
- # the above would hold if we didn't minimize size_w
+ assert carry == -1
a._setshort(k, q-1)
- carry = r_suint(0)
- for i in range(size_w):
- if i+k >= size_v:
- break
+ carry = r_suint(0)
+ i = 0
+ while i < size_w and i+k < size_v:
carry += v._getshort(i+k) + w._getshort(i)
- v._setshort(i+k, r_uint(carry) & SHORT_MASK)
+ v._setshort(i+k, r_uint(carry.value) & SHORT_MASK)
carry >>= SHORT_BIT
+ i += 1
j -= 1
+ k -= 1
a._normalize()
rem, _ = _divrem1(space, v, d)
@@ -830,9 +838,9 @@
if b._getshort(size_b-1) == 0:
size_b -= 1
- if size_b == 0:
- raise OperationError(w_longobj.space.w_ZeroDivisionError,
- w_longobj.space.wrap("long division or modulo by zero"))
+ if b.sign == 0:
+ raise OperationError(space.w_ZeroDivisionError,
+ space.wrap("long division or modulo by zero"))
if (size_a < size_b or
(size_a == size_b and
@@ -852,7 +860,7 @@
# so a = b*z + r.
if a.sign != b.sign:
z.sign = - z.sign
- if z.sign < 0 and rem.sign != 0:
+ if a.sign < 0 and rem.sign != 0:
rem.sign = - rem.sign
return z, rem
@@ -891,29 +899,31 @@
assert x > 0.0
return x * sign, exponent
-# XXX make ldexp and isinf a builtin float support function
-
def isinf(x):
- return x*2 == x
+ return x != 0.0 and x / 2 == x
+
+##def ldexp(x, exp):
+## assert type(x) is float
+## lb1 = LONG_BIT - 1
+## multiplier = float(r_uint(1) << lb1)
+## while exp >= lb1:
+## x *= multiplier
+## exp -= lb1
+## if exp:
+## x *= float(r_uint(1) << exp)
+## return x
-def ldexp(x, exp):
- assert type(x) is float
- lb1 = LONG_BIT - 1
- multiplier = float(r_uint(1) << lb1)
- while exp >= lb1:
- x *= multiplier
- exp -= lb1
- if exp:
- x *= float(r_uint(1) << exp)
- return x
+# note that math.ldexp checks for overflows,
+# while the C ldexp is not guaranteed to.
def _AsDouble(v):
""" Get a C double from a long int object. """
x, e = _AsScaledDouble(v)
if e <= sys.maxint / SHORT_BIT:
- x = ldexp(x, e * SHORT_BIT)
- if not isinf(x):
- return x
+ x = math.ldexp(x, e * SHORT_BIT)
+ #if not isinf(x):
+ # this is checked by math.ldexp
+ return x
raise OverflowError# sorry, "long int too large to convert to float"
def _long_true_divide(space, a, b):
@@ -931,10 +941,61 @@
raise OverflowError
elif aexp < -(sys.maxint / SHORT_BIT):
return 0.0 # underflow to 0
- ad = ldexp(ad, aexp * SHORT_BIT)
- if isinf(ad): # ignore underflow to 0.0
- raise OverflowError
+ ad = math.ldexp(ad, aexp * SHORT_BIT)
+ #if isinf(ad): # ignore underflow to 0.0
+ # raise OverflowError
+ # math.ldexp checks and raises
return ad
except OverflowError:
raise OperationError(space.w_OverflowError,
space.wrap("long/long too large for a float"))
+
+
+def _FromDouble(space, dval):
+ """ Create a new long int object from a C double """
+ neg = 0
+ if isinf(dval):
+ raise OperationError(space.w_OverflowError,
+ space.wrap("cannot convert float infinity to long"))
+ if dval < 0.0:
+ neg = 1
+ dval = -dval
+ frac, expo = math.frexp(dval) # dval = frac*2**expo; 0.0 <= frac < 1.0
+ if expo <= 0:
+ return W_LongObject(space, [r_uint(0)], 0)
+ ndig = (expo-1) // SHORT_BIT + 1 # Number of 'digits' in result
+ digitpairs = (ndig + 1) // 2
+ v = W_LongObject(space, [r_uint(0)] * digitpairs, 1)
+ frac = math.ldexp(frac, (expo-1) % SHORT_BIT + 1)
+ for i in range(ndig-1, -1, -1):
+ bits = int(frac)
+ v._setshort(i, r_uint(bits))
+ frac -= float(bits)
+ frac = math.ldexp(frac, SHORT_BIT)
+ if neg:
+ v.sign = -1
+ return v
+
+def _l_divmod(space, v, w):
+ """
+ The / and % operators are now defined in terms of divmod().
+ The expression a mod b has the value a - b*floor(a/b).
+ The _divrem function gives the remainder after division of
+ |a| by |b|, with the sign of a. This is also expressed
+ as a - b*trunc(a/b), if trunc truncates towards zero.
+ Some examples:
+ a b a rem b a mod b
+ 13 10 3 3
+ -13 10 -3 7
+ 13 -10 3 -7
+ -13 -10 -3 -3
+ So, to get from rem to mod, we have to add b if a and b
+ have different signs. We then subtract one from the 'div'
+ part of the outcome to keep the invariant intact.
+ """
+ div, mod = _divrem(space, v, w)
+ if mod.sign * w.sign == -1:
+ mod = add__Long_Long(space, mod, w)
+ one = W_LongObject(space, [r_uint(1)], 1)
+ div = sub__Long_Long(space, div, one)
+ return div, mod
Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py (original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py Tue Jul 5 20:13:26 2005
@@ -4,6 +4,7 @@
from pypy.objspace.std import longobject as lobj
from pypy.objspace.std.objspace import FailedToImplement
from pypy.rpython.rarithmetic import r_uint
+from pypy.interpreter.error import OperationError
objspacename = 'std'
@@ -112,6 +113,18 @@
f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
assert raises(OverflowError, lobj._AsDouble, f1)
+ def test__FromDouble(self):
+ x = 1234567890.1234567890
+ f1 = lobj._FromDouble(self.space, x)
+ y = lobj._AsDouble(f1)
+ assert f1.longval() == long(x)
+ # check overflow
+ x = 12345.6789e10000000000000000000000000000
+ try:
+ lobj._FromDouble(self.space, x)
+ except OperationError, e:
+ assert e.w_type is self.space.w_OverflowError
+
def test_eq(self):
x = 5858393919192332223L
y = 585839391919233111223311112332L
@@ -289,3 +302,21 @@
def test_getnewargs(self):
assert 0L .__getnewargs__() == (0L,)
assert (-1L) .__getnewargs__() == (-1L,)
+
+ def test_divmod(self):
+ def check_division(x, y):
+ q, r = divmod(x, y)
+ pab, pba = x*y, y*x
+ assert pab == pba
+ assert q == x//y
+ assert r == x%y
+ assert x == q*y + r
+ if y > 0:
+ assert 0 <= r < y
+ else:
+ assert y < r <= 0
+ for x in [-1L, 0L, 1L, 2L ** 100 - 1, -2L ** 100 - 1]:
+ for y in [-105566530L, -1L, 1L, 1034522340L]:
+ print "checking division for %s, %s" % (x, y)
+ check_division(x, y)
+ raises(ZeroDivisionError, "x // 0L")
Modified: pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/llinterp.py Tue Jul 5 20:13:26 2005
@@ -169,7 +169,11 @@
if hasattr(f._obj, 'graph'):
graph = f._obj.graph
else:
- graph = self.llinterpreter.getgraph(f._obj._callable)
+ try:
+ graph = self.llinterpreter.getgraph(f._obj._callable)
+ except KeyError:
+ assert hasattr(f._obj, '_callable'), "don't know how to execute %r" % f
+ return f._obj._callable(*args)
frame = self.__class__(graph, args, self.llinterpreter)
return frame.eval()
Modified: pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rbuiltin.py Tue Jul 5 20:13:26 2005
@@ -9,7 +9,7 @@
from pypy.rpython.robject import pyobj_repr
from pypy.rpython.rfloat import float_repr, FloatRepr
from pypy.rpython import rclass
-
+from pypy.tool import sourcetools
class __extend__(annmodel.SomeBuiltin):
def rtyper_makerepr(self, rtyper):
@@ -87,7 +87,8 @@
def rtype_builtin_int(hop):
if isinstance(hop.args_s[0], annmodel.SomeString):
- raise TyperError('int("string") not supported')
+ assert 1 <= hop.nb_args <= 2
+ return hop.args_r[0].rtype_int(hop)
assert hop.nb_args == 1
return hop.args_r[0].rtype_int(hop)
@@ -240,3 +241,27 @@
includes=("math.h",)) # XXX clean up needed
BUILTIN_TYPER[math.exp] = rtype_math_exp
+
+from pypy.rpython import extfunctable
+
+def make_rtype_extfunc(extfuncinfo):
+ ll_function = extfuncinfo.ll_function
+ if extfuncinfo.ll_annotable:
+ def rtype_extfunc(hop):
+ vars = hop.inputargs(*hop.args_r)
+ return hop.gendirectcall(ll_function, *vars)
+ else:
+ def rtype_extfunc(hop):
+ resulttype = hop.r_result
+ vars = hop.inputargs(*hop.args_r)
+ return hop.llops.genexternalcall(ll_function.__name__, vars, resulttype=resulttype,
+ _callable = ll_function)
+
+ return sourcetools.func_with_new_name(rtype_extfunc,
+ "rtype_extfunc_%s" % extfuncinfo.func.__name__)
+
+# import rtyping information for external functions
+# from the extfunctable.table into our own specific table
+for func, extfuncinfo in extfunctable.table.iteritems():
+ BUILTIN_TYPER[func] = make_rtype_extfunc(extfuncinfo)
+
Modified: pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rmodel.py Tue Jul 5 20:13:26 2005
@@ -226,11 +226,13 @@
def getconcretetype(v):
return getattr(v, 'concretetype', PyObjPtr)
-def getfunctionptr(translator, func, getconcretetype=getconcretetype):
+def getfunctionptr(translator, graphfunc, getconcretetype=getconcretetype, _callable=None):
"""Make a functionptr from the given Python function."""
- graph = translator.getflowgraph(func)
+ graph = translator.getflowgraph(graphfunc)
llinputs = [getconcretetype(v) for v in graph.getargs()]
lloutput = getconcretetype(graph.getreturnvar())
FT = FuncType(llinputs, lloutput)
- return functionptr(FT, func.func_name, graph = graph, _callable = func)
+ if _callable is None:
+ _callable = graphfunc
+ return functionptr(FT, graphfunc.func_name, graph = graph, _callable = _callable)
Modified: pypy/branch/dist-2.4.1/pypy/rpython/rstr.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rstr.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rstr.py Tue Jul 5 20:13:26 2005
@@ -23,8 +23,8 @@
# chars: array of Char
# }
-STR = GcStruct('str', ('hash', Signed),
- ('chars', Array(Char)))
+STR = GcStruct('rpy_string', ('hash', Signed),
+ ('chars', Array(Char)))
SIGNED_ARRAY = GcArray(Signed)
@@ -142,6 +142,16 @@
v_str, v_c1, v_c2 = hop.inputargs(string_repr, char_repr, char_repr)
return hop.gendirectcall(ll_replace_chr_chr, v_str, v_c1, v_c2)
+ def rtype_int(_, hop):
+ if hop.nb_args == 1:
+ v_str, = hop.inputargs(string_repr)
+ c_base = inputconst(Signed, 10)
+ return hop.gendirectcall(ll_int, v_str, c_base)
+ if not hop.args_r[1] == rint.signed_repr:
+ raise TyperError, 'base needs to be an int'
+ v_str, v_base= hop.inputargs(string_repr, rint.signed_repr)
+ return hop.gendirectcall(ll_int, v_str, v_base)
+
def ll_str(s, r):
if typeOf(s) == Char:
return ll_chr2str(s)
@@ -768,6 +778,47 @@
i += 1
return False
+def ll_int(s, base):
+ if not 2 <= base <= 36:
+ raise ValueError
+ chars = s.chars
+ strlen = len(chars)
+ i = 0
+ #XXX: only space is allowed as white space for now
+ while i < strlen and chars[i] == ' ':
+ i += 1
+ if not i < strlen:
+ raise ValueError
+ #check sign
+ sign = 1
+ if chars[i] == '-':
+ sign = -1
+ i += 1
+ elif chars[i] == '+':
+ i += 1;
+ #now get digits
+ val = 0
+ while i < strlen:
+ c = ord(chars[i])
+ if ord('a') <= c <= ord('z'):
+ digit = c - ord('a') + 10
+ elif ord('A') <= c <= ord('Z'):
+ digit = c - ord('A') + 10
+ elif ord('0') <= c <= ord('9'):
+ digit = c - ord('0')
+ else:
+ break
+ if digit >= base:
+ break
+ val = val * base + digit
+ i += 1
+ #skip trailing whitespace
+ while i < strlen and chars[i] == ' ':
+ i += 1
+ if not i == strlen:
+ raise ValueError
+ return sign * val
+
# ____________________________________________________________
#
# Iteration.
Modified: pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/rtyper.py Tue Jul 5 20:13:26 2005
@@ -50,6 +50,7 @@
r = self.getrepr(s_primitive)
self.primitive_to_repr[r.lowleveltype] = r
self.exceptiondata = ExceptionData(self)
+ self.fixednames = self.fixednames.copy()
def getexceptiondata(self):
return self.exceptiondata # built at the end of specialize()
@@ -355,10 +356,10 @@
# __________ utilities __________
- def getfunctionptr(self, func):
+ def getfunctionptr(self, graphfunc, _callable=None):
def getconcretetype(v):
return self.bindingrepr(v).lowleveltype
- return getfunctionptr(self.annotator.translator, func, getconcretetype)
+ return getfunctionptr(self.annotator.translator, graphfunc, getconcretetype, _callable=_callable)
def attachRuntimeTypeInfoFunc(self, GCSTRUCT, func, ARG_GCSTRUCT=None):
self.call_all_setups() # compute ForwardReferences now
@@ -516,20 +517,22 @@
dontcare, spec_function = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s)
# build the 'direct_call' operation
- f = self.rtyper.getfunctionptr(spec_function)
+ f = self.rtyper.getfunctionptr(spec_function, _callable=ll_function)
c = inputconst(typeOf(f), f)
return self.genop('direct_call', [c]+list(args_v),
resulttype = typeOf(f).TO.RESULT)
- def gencapicall(self, cfnname, args_v, resulttype=None, **flags):
+ def genexternalcall(self, fnname, args_v, resulttype=None, **flags):
if isinstance(resulttype, Repr):
resulttype = resulttype.lowleveltype
argtypes = [v.concretetype for v in args_v]
FUNCTYPE = FuncType(argtypes, resulttype or Void)
- f = functionptr(FUNCTYPE, cfnname, external="C", **flags)
+ f = functionptr(FUNCTYPE, fnname, **flags)
cf = inputconst(typeOf(f), f)
return self.genop('direct_call', [cf]+list(args_v), resulttype)
+ def gencapicall(self, cfnname, args_v, resulttype=None, **flags):
+ return self.genexternalcall(cfnname, args_v, resulttype=resulttype, external="C")
# _______________________________________________________________________
# this has the side-effect of registering the unary and binary operations
@@ -540,3 +543,6 @@
from pypy.rpython import rlist, rstr, rtuple, rdict
from pypy.rpython import rclass, rbuiltin, rpbc
from pypy.rpython import rptr
+
+RPythonTyper.fixednames = {}
+RPythonTyper.fixednames[rstr.STR] = True
Modified: pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/test/test_rbuiltin.py Tue Jul 5 20:13:26 2005
@@ -1,4 +1,7 @@
from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test import test_llinterp
+from pypy.objspace.flow import model as flowmodel
+from pypy.tool import udir
from pypy.annotation.builtin import *
import py
@@ -61,6 +64,59 @@
ry = 100 * float(i-10) +0.1
assert fn(rv,ry) == interpret(fn, (rv, ry))
+def enum_direct_calls(translator, func):
+ blocks = []
+ graph = translator.getflowgraph(func)
+ def visit(block):
+ if isinstance(block, flowmodel.Block):
+ blocks.append(block)
+ flowmodel.traverse(visit, graph)
+ for block in blocks:
+ for op in block.operations:
+ if op.opname == 'direct_call':
+ yield op
+
+def test_os_getcwd():
+ import os
+ def fn():
+ return os.getcwd()
+ res = interpret(fn, [])
+ assert ''.join(res.chars) == fn()
+
+def test_os_dup():
+ import os
+ def fn(fd):
+ return os.dup(fd)
+ res = interpret(fn, [0])
+ #try:
+ # os.close(res)
+ #except OSError:
+ # pass
+ count = 0
+ from pypy.rpython import extfunctable
+ for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, fn):
+ cfptr = dir_call.args[0]
+ assert cfptr.value._obj._callable == extfunctable.ll_os_dup
+ count += 1
+ assert count == 1
+
+def test_os_open():
+ tmpdir = str(udir.udir.join("os_open_test"))
+ import os
+ def wr_open(fname):
+ return os.open(fname, os.O_WRONLY|os.O_CREAT)
+ def f():
+ return wr_open(tmpdir)
+ res = interpret(f, [])
+ os.close(res)
+ count = 0
+ from pypy.rpython import extfunctable
+ for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open):
+ cfptr = dir_call.args[0]
+ assert cfptr.value._obj._callable == extfunctable.ll_os_open
+ count += 1
+ assert count == 1
+
def test_pbc_isTrue():
class C:
def f(self):
Modified: pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py (original)
+++ pypy/branch/dist-2.4.1/pypy/rpython/test/test_rstr.py Tue Jul 5 20:13:26 2005
@@ -2,8 +2,8 @@
from pypy.rpython.lltype import *
from pypy.rpython.rstr import parse_fmt_string
from pypy.rpython.rtyper import RPythonTyper, TyperError
-from pypy.rpython.test.test_llinterp import interpret
-
+from pypy.rpython.test.test_llinterp import interpret,find_exception
+from pypy.rpython.llinterp import LLException
def test_simple():
def fn(i):
@@ -356,3 +356,20 @@
s = 'abbccc'
s = s.replace('abb', 'c')
raises (TyperError, interpret, fn, ())
+
+def test_int():
+ s1 = [ '42', '01001', 'abc', 'ABC', '4aBc', ' 12ef ', '+42', 'foo', '42foo', '42.1', '']
+ def fn(i, base):
+ s = s1[i]
+ res = int(s, base)
+ return res
+ for j in (10, 16, 2, 1, 36, 42, -3):
+ for i in range(len(s1)):
+ try:
+ expected = fn(i, j)
+ except ValueError:
+ info = raises(LLException, interpret, fn, [i, j])
+ assert find_exception(info.value) is ValueError
+ else:
+ res = interpret(fn, [i, j])
+ assert res == expected
Modified: pypy/branch/dist-2.4.1/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/c/database.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/c/database.py Tue Jul 5 20:13:26 2005
@@ -21,6 +21,16 @@
self.containernodes = {}
self.containerlist = []
self.namespace = CNameManager()
+ if translator is not None and translator.rtyper is not None:
+ rtyper = translator.rtyper
+ for lltype, nameorflag in rtyper.fixednames.iteritems():
+ if nameorflag is True:
+ self.namespace.make_reserved_names(lltype._name)
+ #else:
+ # self.namespace.make_reserved_names(nameorflag)
+ self.fixednames = rtyper.fixednames
+ else:
+ self.fixednames = {}
self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator)
def gettypedefnode(self, T, varlength=1):
Modified: pypy/branch/dist-2.4.1/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/c/node.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/c/node.py Tue Jul 5 20:13:26 2005
@@ -38,7 +38,10 @@
else:
basename = db.gettypedefnode(STRUCT).name
basename = '%s_len%d' % (basename, varlength)
- self.name = db.namespace.uniquename(basename)
+ if STRUCT in db.fixednames:
+ self.name = basename
+ else:
+ self.name = db.namespace.uniquename(basename)
self.dependencies = {}
self.fields = []
self.prefix = somelettersfrom(STRUCT._name) + '_'
Modified: pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/c/test/test_database.py Tue Jul 5 20:13:26 2005
@@ -196,6 +196,23 @@
db.complete()
dump_on_stdout(db)
+def test_fixedname():
+ def f():
+ return "foo"
+ t = Translator(f)
+ t.annotate([])
+ t.specialize()
+
+ db = LowLevelDatabase(t)
+ S = GcStruct('rpy_string', ('x', Signed))
+ s = malloc(S)
+ s.x = 42
+ db.get(s)
+ Sname = db.gettype(S)
+ db.get(pyobjectptr(f))
+ from pypy.rpython import rstr
+ assert db.gettype(rstr.STR) == "struct rpy_string @"
+ assert Sname != "struct rpy_string @"
def test_malloc():
S = GcStruct('testing', ('x', Signed), ('y', Signed))
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py Tue Jul 5 20:13:26 2005
@@ -3,65 +3,34 @@
from pypy.translator.llvm2.log import log
from pypy.translator.llvm2.node import LLVMNode
from pypy.objspace.flow.model import Constant
+from pypy.translator.llvm2 import varsize
import itertools
log = log.structnode
-count = itertools.count().next
-
-def wrapstr(s):
- return '"%s"' % s
+nextnum = itertools.count().next
class ArrayTypeNode(LLVMNode):
_issetup = False
def __init__(self, db, array):
- self.db = db
assert isinstance(array, lltype.Array)
+
+ self.db = db
self.array = array
- c = count()
- ref_template = wrapstr("%%array.%s." + str(c))
- self.ref = ref_template % array.OF
- self.constructor_ref = wrapstr("%%new.array.%s" % c)
+ # ref is used to reference the arraytype in llvm source
+ # constructor_ref is used to reference the constructor
+ # for the array type in llvm source code
+ # constructor_decl is used to declare the constructor
+ # for the array type (see writeimpl)
+ c = nextnum()
+ self.ref = "%%array.%s.%s" % (c, array.OF)
+ self.constructor_ref = "%%new.array.%s" % c
self.constructor_decl = "%s * %s(int %%len)" % \
(self.ref, self.constructor_ref)
def __str__(self):
return "<ArrayTypeNode %r>" % self.ref
- def writedecl(self, codewriter):
- # declaration for constructor
- codewriter.declare(self.constructor_decl)
-
- def writeimpl(self, codewriter):
- """ this function generates a LLVM function like the following:
- %array = type { int, [0 x double] }
- %array *%NewArray(int %len) {
- ;; Get the offset of the 'len' element of the array from the null
- ;; pointer.
- %size = getelementptr %array* null, int 0, uint 1, %int %len
- %usize = cast double* %size to uint
- %ptr = malloc sbyte, uint %usize
- %result = cast sbyte* %ptr to %array*
- %arraylength = getelementptr %array* %result, int 0, uint 0
- store int %len, int* %arraylength
- ret %array* %result
- }"""
- from pypy.translator.llvm2.atomic import is_atomic
-
- log.writeimpl(self.ref)
- codewriter.openfunc(self.constructor_decl)
- indices = [("uint", 1), ("int", "%len")]
- codewriter.getelementptr("%size", self.ref + "*",
- "null", *indices)
- fromtype = self.db.repr_arg_type(self.array.OF)
- codewriter.cast("%usize", fromtype + "*", "%size", "uint")
- codewriter.malloc("%ptr", "sbyte", "%usize", atomic=is_atomic(self))
- codewriter.cast("%result", "sbyte*", "%ptr", self.ref+"*")
- codewriter.getelementptr("%arraylength", self.ref+"*", "%result", ("uint", 0))
- codewriter.store("int", "%len", "%arraylength")
- codewriter.ret(self.ref+"*", "%result")
- codewriter.closefunc()
-
def setup(self):
self.db.prepare_repr_arg_type(self.array.OF)
self._issetup = True
@@ -72,60 +41,65 @@
def writedatatypedecl(self, codewriter):
codewriter.arraydef(self.ref, self.db.repr_arg_type(self.array.OF))
-# Each ArrayNode is a global constant. This needs to have a specific type of
-# a certain type.
+ def writedecl(self, codewriter):
+ # declaration for constructor
+ codewriter.declare(self.constructor_decl)
+
+ def writeimpl(self, codewriter):
+ log.writeimpl(self.ref)
+ fromtype = self.db.repr_arg_type(self.array.OF)
+ varsize.write_constructor(codewriter, self.ref,
+ self.constructor_decl,
+ fromtype)
class ArrayNode(LLVMNode):
-
_issetup = False
- array_counter = 0
-
def __init__(self, db, value):
self.db = db
- name = '"%%arrayinstance.%s.%s"' % (value._TYPE.OF, ArrayNode.array_counter)
- self.ref = name
self.value = value
- ArrayNode.array_counter += 1
+ self.arraytype = value._TYPE.OF
+ self.ref = "%%arrayinstance.%s.%s" % (value._TYPE.OF, nextnum())
def __str__(self):
return "<ArrayNode %r>" %(self.ref,)
def setup(self):
- T = self.value._TYPE.OF
for item in self.value.items:
- if not isinstance(T, lltype.Primitive):
+ if not isinstance(self.arraytype, lltype.Primitive):
# Create a dummy constant hack XXX
- c = Constant(item, T)
- self.db.prepare_arg(c)
-
+ self.db.prepare_arg(Constant(item, self.arraytype))
self._issetup = True
+ def value_helper(self, value):
+ """ This should really be pushed back to the database??? XXX """
+ if not isinstance(self.arraytype, lltype.Primitive):
+ # Create a dummy constant hack XXX
+ value = self.db.repr_arg(Constant(value, self.arraytype))
+ else:
+ if isinstance(value, str) and len(value) == 1:
+ value = ord(value)
+ value = str(value)
+ return value
+
def getall(self):
- arraylen = len(self.value.items)
+ """ Returns the type and value for this node. """
+ items = self.value.items
+ typeval = self.db.repr_arg_type(self.arraytype)
+ arraylen = len(items)
+
+ type_ = "{ int, [%s x %s] }" % (arraylen, typeval)
+ arrayvalues = ["%s %s" % (typeval,
+ self.value_helper(v)) for v in items]
- res = []
-
- T = self.value._TYPE.OF
- typval = self.db.repr_arg_type(self.value._TYPE.OF)
- for value in self.value.items:
- if not isinstance(T, lltype.Primitive):
- # Create a dummy constant hack XXX
- value = self.db.repr_arg(Constant(value, T))
- else:
- value = repr(value)
- res.append((typval, value))
-
- arrayvalues = ", ".join(["%s %s" % (t, v) for t, v in res])
-
- type_ = "{ int, [%s x %s] }" % (len(self.value.items),
- self.db.repr_arg_type(self.value._TYPE.OF))
-
value = "int %s, [%s x %s] [ %s ]" % (arraylen,
arraylen,
- typval,
- arrayvalues)
+ typeval,
+ ", ".join(arrayvalues))
return type_, value
+ # ______________________________________________________________________
+ # entry points from genllvm
+
def writeglobalconstants(self, codewriter):
type_, values = self.getall()
codewriter.globalinstance(self.ref, type_, values)
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py Tue Jul 5 20:13:26 2005
@@ -1,16 +1,20 @@
from pypy.translator.llvm2.log import log
from pypy.translator.llvm2.structnode import StructTypeNode
from pypy.translator.llvm2.arraynode import ArrayTypeNode
+from pypy.rpython import lltype
log = log.atomic
def is_atomic(node):
+ # XXX is the below really right?
if isinstance(node, StructTypeNode):
- fields = str([getattr(node.struct, name) for name in node.struct._names_without_voids()])
- if '*' not in fields:
+ fields = [getattr(node.struct, name)
+ for name in node.struct._names_without_voids()]
+ fields = [x for x in fields if isinstance(x, lltype.Ptr)]
+ if not fields:
return True #non-pointers only
return False #contains pointer(s)
elif isinstance(node, ArrayTypeNode):
- return False #because they actually are arrays of pointers
+ return not isinstance(node.array.OF, lltype.Ptr)
log("unknown type %s, assuming non-atomic" % str(type(node)))
return False
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py Tue Jul 5 20:13:26 2005
@@ -4,7 +4,7 @@
from pypy.translator.llvm2.genllvm import use_boehm_gc
log = log.codewriter
-show_line_numbers = True
+show_line_numbers = False # True
count = count().next
class CodeWriter(object):
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py Tue Jul 5 20:13:26 2005
@@ -84,7 +84,6 @@
if isinstance(ct, lltype.Struct):
if ct._arrayfld:
- assert False, "HERE"
self.addpending(const_or_var, StructVarsizeNode(self, value))
else:
self.addpending(const_or_var, StructNode(self, value))
@@ -153,6 +152,10 @@
def repr_arg(self, arg):
if (isinstance(arg, Constant) and
isinstance(arg.concretetype, lltype.Primitive)):
+
+ # XXX generalize and test this
+ if isinstance(arg.value, str) and len(arg.value) == 1:
+ return str(ord(arg.value))
return str(arg.value).lower() #False --> false
elif isinstance(arg, Variable):
return "%" + str(arg)
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py Tue Jul 5 20:13:26 2005
@@ -7,19 +7,16 @@
from pypy.translator.llvm2.node import LLVMNode
from pypy.translator.llvm2.atomic import is_atomic
from pypy.translator.llvm2.log import log
+nextnum = py.std.itertools.count().next
log = log.funcnode
class FuncTypeNode(LLVMNode):
- func_type_node_counter = 0
-
def __init__(self, db, type_):
self.db = db
assert isinstance(type_, lltype.FuncType)
self.type_ = type_
- ref = '"ft.%s.%s"' % (type_, FuncTypeNode.func_type_node_counter)
- self.ref = ref.replace(" ", "")
- FuncTypeNode.func_type_node_counter += 1
+ self.ref = 'ft.%s.%s' % (type_, nextnum())
def __str__(self):
return "<FuncTypeNode %r>" % self.ref
@@ -132,6 +129,7 @@
def write_block_operations(self, codewriter, block):
opwriter = OpWriter(self.db, codewriter)
for op in block.operations:
+ codewriter.comment(str(op))
opwriter.write_operation(op)
def write_startblock(self, codewriter, block):
self.write_block_operations(codewriter, block)
@@ -197,6 +195,15 @@
assert meth is not None, "operation %r not found" %(op.opname,)
meth(op)
+ def int_neg(self, op):
+ self.codewriter.binaryop("sub",
+ self.db.repr_arg(op.result),
+ self.db.repr_arg_type(op.args[0]),
+ "0",
+ self.db.repr_arg(op.args[0]),
+ )
+
+
def binaryop(self, op):
name = self.binary_operations[op.opname]
assert len(op.args) == 2
@@ -216,6 +223,7 @@
cast_bool_to_int = cast_primitive
cast_bool_to_uint = uint_is_true = cast_primitive
+ cast_int_to_char = cast_char_to_int = cast_primitive
def int_is_true(self, op):
self.codewriter.binaryop("setne",
@@ -260,7 +268,7 @@
targetvar = self.db.repr_arg(op.result)
arg_type = op.args[0]
assert (isinstance(arg_type, Constant) and
- isinstance(arg_type.value, lltype.Array))
+ isinstance(arg_type.value, (lltype.Array, lltype.Struct)))
#XXX unclean
struct_type = self.db.obj2node[arg_type.value].ref
struct_cons = self.db.obj2node[arg_type.value].constructor_ref
@@ -279,14 +287,19 @@
targetvar = self.db.repr_arg(op.result)
targettype = self.db.repr_arg_type(op.result)
assert targettype != "void"
- if isinstance(op.result.concretetype, lltype.ContainerType):
- # noop
- self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
- else:
- self.codewriter.load(targetvar, targettype, tmpvar)
-
- getsubstruct = getfield
+ self.codewriter.load(targetvar, targettype, tmpvar)
+ def getsubstruct(self, op):
+ typ = self.db.repr_arg_type(op.args[0])
+ typevar = self.db.repr_arg(op.args[0])
+ fieldnames = list(op.args[0].concretetype.TO._names)
+ index = fieldnames.index(op.args[1].value)
+ targetvar = self.db.repr_arg(op.result)
+ self.codewriter.getelementptr(targetvar, typ,
+ typevar, ("uint", index))
+ targettype = self.db.repr_arg_type(op.result)
+ assert targettype != "void"
+
def setfield(self, op):
tmpvar = self.db.repr_tmpvar()
type = self.db.repr_arg_type(op.args[0])
@@ -309,11 +322,7 @@
("uint", 1), (indextype, index))
targetvar = self.db.repr_arg(op.result)
targettype = self.db.repr_arg_type(op.result)
- if isinstance(op.result.concretetype, lltype.ContainerType):
- # noop
- self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
- else:
- self.codewriter.load(targetvar, targettype, tmpvar)
+ self.codewriter.load(targetvar, targettype, tmpvar)
def setarrayitem(self, op):
array = self.db.repr_arg(op.args[0])
@@ -327,6 +336,7 @@
valuevar = self.db.repr_arg(op.args[2])
valuetype = self.db.repr_arg_type(op.args[2])
+ assert valuevar.strip() != '-'
self.codewriter.store(valuetype, valuevar, tmpvar)
def getarraysize(self, op):
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/node.py Tue Jul 5 20:13:26 2005
@@ -1,12 +1,30 @@
class LLVMNode(object):
- def _get_ref(self):
- return self._ref
- def _set_ref(self, ref):
- if hasattr(self, "_ref"):
- raise TypeError, ("can only set ref once! currently: %s" %
- (self._ref,))
- self._ref = ref
- ref = property(_get_ref, _set_ref)
+
+ def ref():
+ def _get_ref(self):
+ return self._ref
+ def _set_ref(self, ref):
+ if hasattr(self, "_ref"):
+ raise TypeError, ("can only set ref once! currently: %s" %
+ (self._ref,))
+ if " " in ref:
+ ref = '"%s"' % (ref,)
+ self._ref = ref
+ return property(_get_ref, _set_ref)
+ ref = ref()
+
+ def constructor_ref():
+ def _get_ref(self):
+ return self._constructor_ref
+ def _set_ref(self, ref):
+ if hasattr(self, "_constructor_ref"):
+ raise TypeError, ("can only set constructor_ref once!"
+ " currently: %s" % (self._constructor_ref,))
+ if " " in ref:
+ ref = '"%s"' % (ref,)
+ self._constructor_ref = ref
+ return property(_get_ref, _set_ref)
+ constructor_ref = constructor_ref()
# __________________ before "implementation" ____________________
def writedatatypedecl(self, codewriter):
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py Tue Jul 5 20:13:26 2005
@@ -2,21 +2,23 @@
from pypy.objspace.flow.model import Block, Constant, Variable, Link
from pypy.translator.llvm2.log import log
from pypy.translator.llvm2.node import LLVMNode
+from pypy.translator.llvm2 import varsize
from pypy.rpython import lltype
+import itertools
+nextnum = itertools.count().next
+
log = log.structnode
class StructTypeNode(LLVMNode):
_issetup = False
- struct_counter = 0
def __init__(self, db, struct):
assert isinstance(struct, lltype.Struct)
self.db = db
self.struct = struct
- self.name = "%s.%s" % (self.struct._name, StructTypeNode.struct_counter)
+ self.name = "%s.%s" % (self.struct._name, nextnum())
self.ref = "%%st.%s" % self.name
- StructTypeNode.struct_counter += 1
def __str__(self):
return "<StructTypeNode %r>" %(self.ref,)
@@ -40,50 +42,37 @@
def __init__(self, db, struct):
super(StructVarsizeTypeNode, self).__init__(db, struct)
- new_var_name = "%%new.st.var.%s" % self.name
- self.constructor_name = "%s * %s(int %%len)" % (self.ref, new_var_name)
+ self.constructor_ref = "%%new.st.var.%s" % (self.name)
+ self.constructor_decl = "%s * %s(int %%len)" % \
+ (self.ref, self.constructor_ref)
def __str__(self):
return "<StructVarsizeTypeNode %r>" %(self.ref,)
def writedecl(self, codewriter):
# declaration for constructor
- codewriter.declare(self.constructor_name)
+ codewriter.declare(self.constructor_decl)
def writeimpl(self, codewriter):
from pypy.translator.llvm2.atomic import is_atomic
log.writeimpl(self.ref)
- codewriter.openfunc(self.constructor_name)
- codewriter.label("block0")
- indices_to_array = [("int", 0)]
- s = self.struct
- while isinstance(s, lltype.Struct):
- last_pos = len(self.struct._names_without_voids()) - 1
- indices_to_array.append(("uint", last_pos))
- s = s._flds.values()[-1]
-
- # Into array and length
- indices = indices_to_array + [("uint", 1), ("int", "%len")]
- codewriter.getelementptr("%size", self.ref + "*",
- "null", *indices)
-
- #XXX is this ok for 64bit?
- codewriter.cast("%sizeu", arraytype + "*", "%size", "uint")
- codewriter.malloc("%resulttmp", "sbyte", "%sizeu", atomic=is_atomic(self))
- codewriter.cast("%result", "sbyte*", "%resulttmp", self.ref + "*")
-
- # remember the allocated length for later use.
- indices = indices_to_array + [("uint", 0)]
- codewriter.getelementptr("%size_ptr", self.ref + "*",
- "%result", *indices)
-
- codewriter.cast("%signedsize", "uint", "%sizeu", "int")
- codewriter.store("int", "%signedsize", "%size_ptr")
-
- codewriter.ret(self.ref + "*", "%result")
- codewriter.closefunc()
+ # build up a list of indices to get to the last
+ # var-sized struct (or rather the according array)
+ indices_to_array = []
+ current = self.struct
+ while isinstance(current, lltype.Struct):
+ last_pos = len(current._names_without_voids()) - 1
+ indices_to_array.append(("uint", last_pos))
+ name = current._names_without_voids()[-1]
+ current = current._flds[name]
+ assert isinstance(current, lltype.Array)
+ arraytype = self.db.repr_arg_type(current.OF)
+ # XXX write type info as a comment
+ varsize.write_constructor(codewriter,
+ self.ref, self.constructor_decl, arraytype,
+ indices_to_array)
def cast_global(toptr, from_, name):
s = "cast(%s* getelementptr (%s* %s, int 0) to %s)" % (from_,
@@ -94,14 +83,11 @@
class StructNode(LLVMNode):
_issetup = False
- struct_counter = 0
def __init__(self, db, value):
self.db = db
- name = "%s.%s" % (value._TYPE._name, StructNode.struct_counter)
- self.ref = "%%stinstance.%s" % name
self.value = value
- StructNode.struct_counter += 1
+ self.ref = "%%stinstance.%s.%s" % (value._TYPE._name, nextnum())
def __str__(self):
return "<StructNode %r>" %(self.ref,)
@@ -127,6 +113,8 @@
if not isinstance(T, lltype.Primitive):
# Create a dummy constant hack XXX
c = Constant(value, T)
+
+ # Needs some sanitisation
x = self.db.obj2node[c]
value = self.db.repr_arg(c)
t, v = x.getall()
@@ -149,10 +137,10 @@
return "<StructVarsizeNode %r>" %(self.ref,)
def getall(self):
-
res = []
- for name in self.value._TYPE._names_without_voids()[:-1]:
- T = self.value._TYPE._flds[name]
+ type_ = self.value._TYPE
+ for name in type_._names_without_voids()[:-1]:
+ T = type_._flds[name]
value = getattr(self.value, name)
if not isinstance(T, lltype.Primitive):
# Create a dummy constant hack XXX
@@ -162,16 +150,19 @@
res.append((self.db.repr_arg_type(T), value))
# Special case for varsized arrays
- self.value._TYPE._names_without_voids()[-1]
- x = self.db.obj2node[Constant(value, T)]
- t, v = x.get_values()
- res.append((t, "{%s}" % v))
+ name = type_._names_without_voids()[-1]
+ T = type_._flds[name]
+ assert not isinstance(T, lltype.Primitive)
+ value = getattr(self.value, name)
+ c = Constant(value, T)
+ x = self.db.obj2node[c]
+ t, v = x.getall()
+
+ #value = self.db.repr_arg(c)
+ value = cast_global(self.db.repr_arg_type(T), t, "{%s}" % v)
+ res.append((self.db.repr_arg_type(T), value))
- s = self.value._TYPE
- fields = [getattr(s, name) for name in s._names_without_voids()[-1]]
- l = [self.db.repr_arg_type(field) for field in fields]
- l += t
- typestr = "{ %s }" % ", ".join(l)
+ typestr = self.db.repr_arg_type(type_)
values = ", ".join(["%s %s" % (t, v) for t, v in res])
return typestr, values
Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py (original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py Tue Jul 5 20:13:26 2005
@@ -12,7 +12,7 @@
from pypy.rpython.rtyper import RPythonTyper
from pypy.rpython.rarithmetic import r_uint
-py.log.setconsumer("genllvm", py.log.STDOUT)
+#py.log.setconsumer("genllvm", py.log.STDOUT)
py.log.setconsumer("genllvm database prepare", None)
@@ -288,7 +288,7 @@
f = compile_function(list_getitem_pbc, [int])
assert f(0) == 1
assert f(1) == 2
-
+
def test_list_list_getitem_pbc():
l = [[0, 1], [0, 1]]
def list_list_getitem_pbc(i):
@@ -314,11 +314,17 @@
for j in range(6):
assert f(i,j) == list_basic_ops(i,j)
+def test_string_simple():
+ def string_simple(i):
+ return ord(str(i))
+ f = compile_function(string_simple, [int], view=False)
+ assert f(0)
+
def Xtest_string_getitem1():
l = "Hello, World"
- def string_test(i):
+ def string_getitem1(i):
return l[i]
- f = compile_function(string_test, [int], view=True)
+ f = compile_function(string_getitem1, [int], view=True)
assert f(0) == ord("H")
def DONOT_test_string_getitem2():
More information about the Pypy-commit
mailing list