[pypy-commit] pypy default: Remove get_display_text override

2015-11-13 Thread krono
Author: Tobias Pape 
Branch: 
Changeset: r80654:56da80b53db3
Date: 2015-11-13 09:08 +0100
http://bitbucket.org/pypy/pypy/changeset/56da80b53db3/

Log:Remove get_display_text override

(seems to be a hg merge artifact)

diff --git a/rpython/jit/metainterp/history.py 
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -541,9 +541,6 @@
 self.name,
 ', '.join([box.repr(memo) for box in self.inputargs]))
 
-def get_display_text(self):# for graphpage.py
-return self.name + '\n' + repr(self.inputargs)
-
 def show(self, errmsg=None):
 "NOT_RPYTHON"
 from rpython.jit.metainterp.graphpage import display_procedures
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy s390x-backend: completed implementation for int_is_true, int_is_zero. added flush_cc method and fixed the LARL problem (test suite provided wrong number to gnu asm)

2015-11-13 Thread plan_rich
Author: Richard Plangger 
Branch: s390x-backend
Changeset: r80655:7e4f29d5c048
Date: 2015-11-13 10:18 +0100
http://bitbucket.org/pypy/pypy/changeset/7e4f29d5c048/

Log:completed implementation for int_is_true, int_is_zero. added
flush_cc method and fixed the LARL problem (test suite provided
wrong number to gnu asm)

diff --git a/rpython/jit/backend/zarch/assembler.py 
b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -357,6 +357,26 @@
 targettoken._ll_loop_code += rawstart
 self.target_tokens_currently_compiling = None
 
+def flush_cc(self, condition, result_loc):
+# After emitting an instruction that leaves a boolean result in
+# a condition code (cc), call this.  In the common case, result_loc
+# will be set to 'fp' by the regalloc, which in this case means
+# "propagate it between this operation and the next guard by keeping
+# it in the cc".  In the uncommon case, result_loc is another
+# register, and we emit a load from the cc into this register.
+assert self.guard_success_cc == c.cond_none
+if result_loc is r.SPP:
+self.guard_success_cc = condition
+else:
+# sadly we cannot use LOCGHI
+# it is included in some extension that seem to be NOT installed
+# by default.
+self.mc.LGHI(r.SCRATCH, l.imm(1))
+self.mc.LOCGR(result_loc, r.SCRATCH, condition)
+self.mc.LGHI(r.SCRATCH, l.imm(0))
+self.mc.LOCGR(result_loc, r.SCRATCH, c.negate(condition))
+
+
 def _assemble(self, regalloc, inputargs, operations):
 self._regalloc = regalloc
 self.guard_success_cc = c.cond_none
diff --git a/rpython/jit/backend/zarch/instruction_builder.py 
b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -133,13 +133,13 @@
 
 def build_rre(mnemonic, (opcode1,opcode2), argtypes='r,r'):
 @builder.arguments(argtypes)
-def encode_rr(self, reg1, reg2):
+def encode_rre(self, reg1, reg2):
 self.writechar(opcode1)
 self.writechar(opcode2)
 self.writechar('\x00')
 operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
 self.writechar(chr(operands))
-return encode_rr
+return encode_rre
 
 def build_rx(mnemonic, (opcode,)):
 @builder.arguments('r/m,bid')
@@ -277,14 +277,24 @@
 encode_base_displace(self, base_displace)
 return encode_rs
 
-def build_rsy(mnemonic, (opcode1,opcode2)):
+@always_inline
+def _encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace):
+self.writechar(opcode1)
+self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
+encode_base_displace_long(self, base_displace)
+self.writechar(opcode2)
+
+def build_rsy_a(mnemonic, (opcode1,opcode2)):
 @builder.arguments('r,r,bdl')
-def encode_ssa(self, reg1, reg3, base_displace):
-self.writechar(opcode1)
-self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
-encode_base_displace_long(self, base_displace)
-self.writechar(opcode2)
-return encode_ssa
+def encode_rsy(self, reg1, reg3, base_displace):
+_encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace)
+return encode_rsy
+
+def build_rsy_b(mnemonic, (opcode1,opcode2)):
+@builder.arguments('r,bdl,r')
+def encode_rsy(self, reg1, base_displace, reg3):
+_encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace)
+return encode_rsy
 
 def build_rsi(mnemonic, (opcode,)):
 br = is_branch_relative(mnemonic)
@@ -298,10 +308,10 @@
 self.write_i16(imm16 & BIT_MASK_16)
 return encode_ri
 
-def build_rie(mnemonic, (opcode1,opcode2)):
+def build_rie_e(mnemonic, (opcode1,opcode2)):
 br = is_branch_relative(mnemonic)
 @builder.arguments('r,r,i16')
-def encode_ri(self, reg1, reg2, imm16):
+def encode_rie_e(self, reg1, reg2, imm16):
 self.writechar(opcode1)
 byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
 self.writechar(chr(byte))
@@ -310,18 +320,45 @@
 self.write_i16(imm16 & BIT_MASK_16)
 self.writechar(chr(0x0))
 self.writechar(opcode2)
-return encode_ri
+return encode_rie_e
 
-def build_rrf(mnemonic, (opcode1,opcode2), argtypes):
+def build_rie_a(mnemonic, (opcode1,opcode2)):
+br = is_branch_relative(mnemonic)
+@builder.arguments('r,i16,r/m')
+def encode_rie_a(self, reg1, imm16, mask):
+self.writechar(opcode1)
+byte = (reg1 & BIT_MASK_4) << 4 | (mask & BIT_MASK_4)
+self.writechar(chr(byte))
+if br:
+imm16 = imm16 >> 1
+self.write_i16(imm16 & BIT_MASK_16)
+self.writechar(chr(0x0))
+self.writechar(opcode2)
+return encode_rie_a
+
+build_rie_g = build_rie_a

[pypy-commit] pypy stmgc-c8: Merge

2015-11-13 Thread Raemi
Author: Remi Meier 
Branch: stmgc-c8
Changeset: r80657:5a0d15e9f510
Date: 2015-11-13 10:40 +0100
http://bitbucket.org/pypy/pypy/changeset/5a0d15e9f510/

Log:Merge

diff --git a/pypy/module/pypystm/hashtable.py b/pypy/module/pypystm/hashtable.py
--- a/pypy/module/pypystm/hashtable.py
+++ b/pypy/module/pypystm/hashtable.py
@@ -2,6 +2,7 @@
 The class pypystm.hashtable, mapping integers to objects.
 """
 
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
@@ -78,6 +79,55 @@
  for i in range(count)]
 return space.newlist(lst_w)
 
+def iterkeys_w(self, space):
+return W_HashtableIterKeys(self.h)
+
+def itervalues_w(self, space):
+return W_HashtableIterValues(self.h)
+
+def iteritems_w(self, space):
+return W_HashtableIterItems(self.h)
+
+
+class W_BaseHashtableIter(W_Root):
+_immutable_fields_ = ["hiter"]
+
+def __init__(self, hobj):
+self.hiter = hobj.iterentries()
+
+def descr_iter(self, space):
+return self
+
+def descr_length_hint(self, space):
+# xxx overestimate: doesn't remove the items already yielded,
+# and uses the faster len_estimate()
+return space.wrap(self.hiter.hashtable.len_estimate())
+
+def descr_next(self, space):
+try:
+entry = self.hiter.next()
+except StopIteration:
+raise OperationError(space.w_StopIteration, space.w_None)
+return self.get_final_value(space, entry)
+
+def _cleanup_(self):
+raise Exception("seeing a prebuilt %r object" % (
+self.__class__,))
+
+class W_HashtableIterKeys(W_BaseHashtableIter):
+def get_final_value(self, space, entry):
+return space.wrap(intmask(entry.index))
+
+class W_HashtableIterValues(W_BaseHashtableIter):
+def get_final_value(self, space, entry):
+return cast_gcref_to_instance(W_Root, entry.object)
+
+class W_HashtableIterItems(W_BaseHashtableIter):
+def get_final_value(self, space, entry):
+return space.newtuple([
+space.wrap(intmask(entry.index)),
+cast_gcref_to_instance(W_Root, entry.object)])
+
 
 def W_Hashtable___new__(space, w_subtype):
 r = space.allocate_instance(W_Hashtable, w_subtype)
@@ -98,4 +148,16 @@
 keys= interp2app(W_Hashtable.keys_w),
 values  = interp2app(W_Hashtable.values_w),
 items   = interp2app(W_Hashtable.items_w),
+
+__iter__   = interp2app(W_Hashtable.iterkeys_w),
+iterkeys   = interp2app(W_Hashtable.iterkeys_w),
+itervalues = interp2app(W_Hashtable.itervalues_w),
+iteritems  = interp2app(W_Hashtable.iteritems_w),
 )
+
+W_BaseHashtableIter.typedef = TypeDef(
+"hashtable_iter",
+__iter__ = interp2app(W_BaseHashtableIter.descr_iter),
+next = interp2app(W_BaseHashtableIter.descr_next),
+__length_hint__ = interp2app(W_BaseHashtableIter.descr_length_hint),
+)
diff --git a/pypy/module/pypystm/stmdict.py b/pypy/module/pypystm/stmdict.py
--- a/pypy/module/pypystm/stmdict.py
+++ b/pypy/module/pypystm/stmdict.py
@@ -2,6 +2,7 @@
 The class pypystm.stmdict, giving a part of the regular 'dict' interface
 """
 
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
@@ -215,10 +216,6 @@
 def len_w(self, space):
 return space.wrap(self.get_length())
 
-def iter_w(self, space):
-# not a real lazy iterator!
-return space.iter(self.keys_w(space))
-
 def keys_w(self, space):
 return space.newlist(self.get_keys_values_w(offset=0))
 
@@ -228,6 +225,70 @@
 def items_w(self, space):
 return space.newlist(self.get_items_w(space))
 
+def iterkeys_w(self, space):
+return W_STMDictIterKeys(self.h)
+
+def itervalues_w(self, space):
+return W_STMDictIterValues(self.h)
+
+def iteritems_w(self, space):
+return W_STMDictIterItems(self.h)
+
+
+class W_BaseSTMDictIter(W_Root):
+_immutable_fields_ = ["hiter"]
+next_from_same_hash = 0
+
+def __init__(self, hobj):
+self.hiter = hobj.iterentries()
+
+def descr_iter(self, space):
+return self
+
+def descr_length_hint(self, space):
+# xxx estimate: doesn't remove the items already yielded,
+# and uses the faster len_estimate(); on the other hand,
+# counts only one for every 64-bit hash value
+return space.wrap(self.hiter.hashtable.len_estimate())
+
+def descr_next(self, space):
+if self.next_from_same_hash == 0:  # common case
+try:
+entry = self.hiter.next()
+except StopIteration:
+raise OperationError(space.w_StopIteration, space.w_None)
+   

[pypy-commit] pypy default: test_pystrtod.py edited online with Bitbucket

2015-11-13 Thread yufeiz
Author: Faye Zhao 
Branch: 
Changeset: r80659:1294e75456b2
Date: 2015-11-13 00:18 +
http://bitbucket.org/pypy/pypy/changeset/1294e75456b2/

Log:test_pystrtod.py edited online with Bitbucket

diff --git a/pypy/module/cpyext/test/test_pystrtod.py 
b/pypy/module/cpyext/test/test_pystrtod.py
--- a/pypy/module/cpyext/test/test_pystrtod.py
+++ b/pypy/module/cpyext/test/test_pystrtod.py
@@ -1,5 +1,6 @@
 import math
 
+from pypy.module.cpyext import pystrtod
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from rpython.rtyper.lltypesystem import rffi
 from rpython.rtyper.lltypesystem import lltype
@@ -91,3 +92,76 @@
 api.PyErr_Clear()
 rffi.free_charp(s)
 lltype.free(endp, flavor='raw')
+
+
+class TestPyOS_double_to_string(BaseApiTest):
+
+def test_format_code(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(150.0, 'e', 1, 0, ptype)
+assert '1.5e+02' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_precision(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(3.14159269397, 'g', 5, 0, ptype)
+assert '3.1416' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_flags_sign(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(-3.14, 'g', 3, 1, ptype)
+assert '-3.14' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_flags_add_dot_0(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(3, 'g', 5, 2, ptype)
+assert '3.0' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_flags_alt(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(314., 'g', 3, 4, ptype)
+assert '314.' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_ptype_nan(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(float('nan'), 'g', 3, 4, ptype)
+assert 'nan' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_NAN == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_ptype_infinity(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(1e200 * 1e200, 'g', 0, 0, ptype)
+assert 'inf' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_INFINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_ptype_null(self, api):
+ptype = lltype.nullptr(rffi.INTP.TO)
+r = api.PyOS_double_to_string(3.14, 'g', 3, 0, ptype)
+assert '3.14' == rffi.charp2str(r)
+assert ptype == lltype.nullptr(rffi.INTP.TO)
+rffi.free_charp(r)
\ No newline at end of file
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: pystrtod.py edited online with Bitbucket

2015-11-13 Thread yufeiz
Author: Faye Zhao 
Branch: 
Changeset: r80658:4d1ea0f21109
Date: 2015-11-13 00:16 +
http://bitbucket.org/pypy/pypy/changeset/4d1ea0f21109/

Log:pystrtod.py edited online with Bitbucket

diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py
--- a/pypy/module/cpyext/pystrtod.py
+++ b/pypy/module/cpyext/pystrtod.py
@@ -9,6 +9,18 @@
 from rpython.rtyper.lltypesystem import rffi
 
 
+# PyOS_double_to_string's "type", if non-NULL, will be set to one of:
+Py_DTST_FINITE = 0
+Py_DTST_INFINITE = 1
+Py_DTST_NAN = 2
+
+# Match the "type" back to values in CPython
+DOUBLE_TO_STRING_TYPES_MAP = {
+rfloat.DIST_FINITE: Py_DTST_FINITE,
+rfloat.DIST_INFINITY: Py_DTST_INFINITE,
+rfloat.DIST_NAN: Py_DTST_NAN
+}
+
 @cpython_api([rffi.CCHARP, rffi.CCHARPP, PyObject], rffi.DOUBLE, error=-1.0)
 @jit.dont_look_inside   # direct use of _get_errno()
 def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
@@ -68,3 +80,40 @@
 finally:
 if not user_endptr:
 lltype.free(endptr, flavor='raw')
+
+@cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, 
rffi.INTP], rffi.CCHARP)
+def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
+"""Convert a double val to a string using supplied
+format_code, precision, and flags.
+
+format_code must be one of 'e', 'E', 'f', 'F',
+'g', 'G' or 'r'.  For 'r', the supplied precision
+must be 0 and is ignored.  The 'r' format code specifies the
+standard repr() format.
+
+flags can be zero or more of the values Py_DTSF_SIGN,
+Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:
+
+Py_DTSF_SIGN means to always precede the returned string with a sign
+character, even if val is non-negative.
+
+Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
+like an integer.
+
+Py_DTSF_ALT means to apply "alternate" formatting rules.  See the
+documentation for the PyOS_snprintf() '#' specifier for
+details.
+
+If ptype is non-NULL, then the value it points to will be set to one of
+Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
+val is a finite number, an infinite number, or not a number, respectively.
+
+The return value is a pointer to buffer with the converted string or
+NULL if the conversion failed. The caller is responsible for freeing the
+returned string by calling PyMem_Free().
+"""
+buffer, rtype = rfloat.double_to_string(val, format_code, precision, flags)
+if ptype != lltype.nullptr(rffi.INTP.TO):
+ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype])
+bufp = rffi.str2charp(buffer)
+return bufp
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Merged in yufeiz/pypy-pyos_double_to_string (pull request #357)

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r80660:f686da796f5e
Date: 2015-11-13 11:30 +0100
http://bitbucket.org/pypy/pypy/changeset/f686da796f5e/

Log:Merged in yufeiz/pypy-pyos_double_to_string (pull request #357)

Add PyOS_double_to_string and unit tests to cpyext

diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py
--- a/pypy/module/cpyext/pystrtod.py
+++ b/pypy/module/cpyext/pystrtod.py
@@ -9,6 +9,18 @@
 from rpython.rtyper.lltypesystem import rffi
 
 
+# PyOS_double_to_string's "type", if non-NULL, will be set to one of:
+Py_DTST_FINITE = 0
+Py_DTST_INFINITE = 1
+Py_DTST_NAN = 2
+
+# Match the "type" back to values in CPython
+DOUBLE_TO_STRING_TYPES_MAP = {
+rfloat.DIST_FINITE: Py_DTST_FINITE,
+rfloat.DIST_INFINITY: Py_DTST_INFINITE,
+rfloat.DIST_NAN: Py_DTST_NAN
+}
+
 @cpython_api([rffi.CCHARP, rffi.CCHARPP, PyObject], rffi.DOUBLE, error=-1.0)
 @jit.dont_look_inside   # direct use of _get_errno()
 def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
@@ -68,3 +80,40 @@
 finally:
 if not user_endptr:
 lltype.free(endptr, flavor='raw')
+
+@cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, 
rffi.INTP], rffi.CCHARP)
+def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
+"""Convert a double val to a string using supplied
+format_code, precision, and flags.
+
+format_code must be one of 'e', 'E', 'f', 'F',
+'g', 'G' or 'r'.  For 'r', the supplied precision
+must be 0 and is ignored.  The 'r' format code specifies the
+standard repr() format.
+
+flags can be zero or more of the values Py_DTSF_SIGN,
+Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:
+
+Py_DTSF_SIGN means to always precede the returned string with a sign
+character, even if val is non-negative.
+
+Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
+like an integer.
+
+Py_DTSF_ALT means to apply "alternate" formatting rules.  See the
+documentation for the PyOS_snprintf() '#' specifier for
+details.
+
+If ptype is non-NULL, then the value it points to will be set to one of
+Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
+val is a finite number, an infinite number, or not a number, respectively.
+
+The return value is a pointer to buffer with the converted string or
+NULL if the conversion failed. The caller is responsible for freeing the
+returned string by calling PyMem_Free().
+"""
+buffer, rtype = rfloat.double_to_string(val, format_code, precision, flags)
+if ptype != lltype.nullptr(rffi.INTP.TO):
+ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype])
+bufp = rffi.str2charp(buffer)
+return bufp
diff --git a/pypy/module/cpyext/test/test_pystrtod.py 
b/pypy/module/cpyext/test/test_pystrtod.py
--- a/pypy/module/cpyext/test/test_pystrtod.py
+++ b/pypy/module/cpyext/test/test_pystrtod.py
@@ -1,5 +1,6 @@
 import math
 
+from pypy.module.cpyext import pystrtod
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from rpython.rtyper.lltypesystem import rffi
 from rpython.rtyper.lltypesystem import lltype
@@ -91,3 +92,76 @@
 api.PyErr_Clear()
 rffi.free_charp(s)
 lltype.free(endp, flavor='raw')
+
+
+class TestPyOS_double_to_string(BaseApiTest):
+
+def test_format_code(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(150.0, 'e', 1, 0, ptype)
+assert '1.5e+02' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_precision(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(3.14159269397, 'g', 5, 0, ptype)
+assert '3.1416' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_flags_sign(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(-3.14, 'g', 3, 1, ptype)
+assert '-3.14' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_flags_add_dot_0(self, api):
+ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+r = api.PyOS_double_to_string(3, 'g', 5, 2, ptype)
+assert '3.0' == rffi.charp2str(r)
+type_value = rffi.cast(lltype.Signed, ptype[0])
+assert pystrtod.Py_DTST_FINITE == type_value
+rffi.free_charp(r)
+lltype.free(ptype, flavor='raw')
+
+def test_flags_alt(self, api):
+ 

[pypy-commit] pypy s390x-backend: added test for an overflow operations, added regalloc for guards (overflow, exception). they are not yet fully functional

2015-11-13 Thread plan_rich
Author: Richard Plangger 
Branch: s390x-backend
Changeset: r80661:d49e13685df3
Date: 2015-11-13 12:52 +0100
http://bitbucket.org/pypy/pypy/changeset/d49e13685df3/

Log:added test for an overflow operations, added regalloc for guards
(overflow, exception). they are not yet fully functional

diff --git a/rpython/jit/backend/zarch/conditions.py 
b/rpython/jit/backend/zarch/conditions.py
--- a/rpython/jit/backend/zarch/conditions.py
+++ b/rpython/jit/backend/zarch/conditions.py
@@ -5,10 +5,11 @@
 EQ = loc.imm(0x8)
 LT = loc.imm(0x4)
 GT = loc.imm(0x2)
-OF = loc.imm(0x1)
+OF = loc.imm(0x1) # overflow
 LE = loc.imm(EQ.value | LT.value)
 GE = loc.imm(EQ.value | GT.value)
 NE = loc.imm(LT.value | GT.value)
+NO = loc.imm(0xe) # NO overflow
 ANY = loc.imm(0xf)
 
 cond_none = loc.imm(0x0)
diff --git a/rpython/jit/backend/zarch/helper/assembler.py 
b/rpython/jit/backend/zarch/helper/assembler.py
--- a/rpython/jit/backend/zarch/helper/assembler.py
+++ b/rpython/jit/backend/zarch/helper/assembler.py
@@ -76,7 +76,7 @@
 getattr(self.mc, func)(l0, l0, l1)
 return f
 
-def gen_emit_rr_or_rpool(rr_func, rp_func):
+def gen_emit_rr_or_rpool(rr_func, rp_func, overflow=False):
 """ the parameters can either be both in registers or
 the first is in the register, second in literal pool.
 """
@@ -88,4 +88,34 @@
 getattr(self.mc, rp_func)(l0, l1)
 else:
 getattr(self.mc, rr_func)(l0, l1)
+if overflow:
+self.guard_success_cc = c.OF
 return f
+
+def gen_emit_imm_pool_rr(imm_func, pool_func, rr_func, overflow=False):
+def emit(self, op, arglocs, regalloc):
+l0, l1 = arglocs
+if l1.is_in_pool():
+getattr(self.mc, pool_func)(l0, l1)
+elif l1.is_imm():
+getattr(self.mc, imm_func)(l0, l1)
+else:
+getattr(self.mc, rr_func)(l0, l1)
+if overflow:
+self.guard_success_cc = c.OF
+return emit
+
+def gen_emit_pool_or_rr_evenodd(pool_func, rr_func):
+def emit(self, op, arglocs, regalloc):
+lr, lq, l1 = arglocs # lr == remainer, lq == quotient
+# when entering the function lr contains the dividend
+# after this operation either lr or lq is used further
+assert l1.is_in_pool() or not l1.is_imm() , "imm divider not supported"
+# remainer is always a even register r0, r2, ... , r14
+assert lr.is_even()
+assert lq.is_odd()
+if l1.is_in_pool():
+self.mc.DSG(lr, l1)
+else:
+self.mc.DSGR(lr, l1)
+return emit
diff --git a/rpython/jit/backend/zarch/opassembler.py 
b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -1,5 +1,6 @@
 from rpython.jit.backend.zarch.helper.assembler import (gen_emit_cmp_op,
-gen_emit_rr_or_rpool, gen_emit_shift)
+gen_emit_rr_or_rpool, gen_emit_shift, gen_emit_pool_or_rr_evenodd,
+gen_emit_imm_pool_rr)
 from rpython.jit.backend.zarch.codebuilder import ZARCHGuardToken
 import rpython.jit.backend.zarch.conditions as c
 import rpython.jit.backend.zarch.registers as r
@@ -9,70 +10,17 @@
 class IntOpAssembler(object):
 _mixin_ = True
 
-def emit_int_add(self, op, arglocs, regalloc):
-l0, l1 = arglocs
-if l1.is_imm():
-self.mc.AGFI(l0, l1)
-elif l1.is_in_pool():
-self.mc.AG(l0, l1)
-else:
-self.mc.AGR(l0, l1)
+emit_int_add = gen_emit_imm_pool_rr('AGFI','AG','AGR')
+emit_int_add_ovf = gen_emit_imm_pool_rr('AGFI','AG','AGR', overflow=True)
+emit_int_sub = gen_emit_rr_or_rpool('SGR', 'SG')
+emit_int_sub_ovf = gen_emit_rr_or_rpool('SGR', 'SG', overflow=True)
+emit_int_mul = gen_emit_imm_pool_rr('MSGFI', 'MSG', 'MSGR')
 
-def emit_int_mul(self, op, arglocs, regalloc):
-l0, l1 = arglocs
-if l1.is_imm():
-self.mc.MSGFI(l0, l1)
-elif l1.is_in_pool():
-self.mc.MSG(l0, l1)
-else:
-self.mc.MSGR(l0, l1)
-
-def emit_int_floordiv(self, op, arglocs, regalloc):
-lr, lq, l1 = arglocs # lr == remainer, lq == quotient
-# when entering the function lr contains the dividend
-# after this operation either lr or lq is used further
-assert l1.is_in_pool() or not l1.is_imm() , "imm divider not supported"
-# remainer is always a even register r0, r2, ... , r14
-assert lr.is_even()
-assert lq.is_odd()
-if l1.is_in_pool():
-self.mc.DSG(lr, l1)
-else:
-self.mc.DSGR(lr, l1)
-
-def emit_uint_floordiv(self, op, arglocs, regalloc):
-lr, lq, l1 = arglocs # lr == remainer, lq == quotient
-# when entering the function lr contains the dividend
-# after this operation either lr or lq is used further
-assert l1.is_in_pool() or not l1.is_imm() , "imm divider not supported"
-

[pypy-commit] cffi static-callback: Finally found a way to arrange the generated code

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2380:b506706f5a75
Date: 2015-11-13 13:12 +0100
http://bitbucket.org/cffi/cffi/changeset/b506706f5a75/

Log:Finally found a way to arrange the generated code

diff --git a/cffi/parse_c_type.h b/cffi/parse_c_type.h
--- a/cffi/parse_c_type.h
+++ b/cffi/parse_c_type.h
@@ -160,6 +160,17 @@
 const char *error_message;
 };
 
+struct _cffi_callpy_s {
+const char *name;
+const struct _cffi_type_context_s *ctx;
+int type_index;
+void *direct_fn;
+void *reserved;
+};
+
+extern void _cffi_call_python(struct _cffi_callpy_s *, void *);
+
+
 #ifdef _CFFI_INTERNAL
 static int parse_c_type(struct _cffi_parse_info_s *info, const char *input);
 static int search_in_globals(const struct _cffi_type_context_s *ctx,
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -227,6 +227,7 @@
 self._lsts = {}
 for step_name in self.ALL_STEPS:
 self._lsts[step_name] = []
+self._callpy = []
 self._seen_struct_unions = set()
 self._generate("ctx")
 self._add_missing_struct_unions()
@@ -360,6 +361,9 @@
 prnt('};')
 prnt()
 #
+if self._callpy:
+self._generate_delayed_callpy()
+#
 # the init function
 base_module_name = self.module_name.split('.')[-1]
 prnt('#ifdef PYPY_VERSION')
@@ -1108,6 +1112,71 @@
 GlobalExpr(name, '_cffi_var_%s' % name, CffiOp(op, type_index)))
 
 # --
+# CFFI_CALL_PYTHON
+
+def _generate_cpy_call_python_collecttype(self, tp, name):
+self._do_collect_type(tp.as_raw_function())
+
+def _generate_cpy_call_python_decl(self, tp, name):
+pass# the function is delayed and only generated later
+
+def _generate_cpy_call_python_ctx(self, tp, name):
+if self.target_is_python:
+raise ffiplatform.VerificationError(
+"cannot use CFFI_CALL_PYTHON in the ABI mode")
+if tp.ellipsis:
+raise NotImplementedError("CFFI_CALL_PYTHON with a vararg 
function")
+self._callpy.append((tp, name))
+
+def _generate_delayed_callpy(self):
+#
+# Write static headers for all the call-python functions
+prnt = self._prnt
+function_sigs = []
+for tp, name in self._callpy:
+arguments = []
+context = 'argument of %s' % name
+for i, type in enumerate(tp.args):
+arg = type.get_c_name(' a%d' % i, context)
+arguments.append(arg)
+#
+repr_arguments = ', '.join(arguments)
+repr_arguments = repr_arguments or 'void'
+name_and_arguments = '%s(%s)' % (name, repr_arguments)
+context = 'result of %s' % name
+sig = tp.result.get_c_name(name_and_arguments, context)
+function_sigs.append(sig)
+prnt('static %s;' % sig)
+prnt()
+#
+# Write the _cffi_callpy array, which is not constant: a few
+# fields (notably "reserved") can be modified by _cffi_backend
+prnt('static struct _cffi_callpy_s _cffi_callpys[%d] = {' %
+ (len(self._callpy),))
+for tp, name in self._callpy:
+type_index = self._typesdict[tp.as_raw_function()]
+prnt('  { "%s", &_cffi_type_context, %d, (void *)&%s },' % (
+name, type_index, name))
+prnt('};')
+prnt()
+#
+# Write the implementation of the functions declared above
+for (tp, name), sig in zip(self._callpy, function_sigs):
+prnt('static %s' % sig)
+prnt('{')
+prnt('  uint64_t a[%d];' % max(len(tp.args), 1))
+prnt('  char *p = (char *)a;')
+for i, type in enumerate(tp.args):
+prnt('  *(%s)(p + %d) = a%d;' % (type.get_c_name('*'), i*8, i))
+prnt('  _cffi_call_python(_cffi_callpys + 0, a);')
+if isinstance(tp.result, model.VoidType):
+prnt('  (void)p;')
+else:
+prnt('  return *(%s)p;' % (tp.result.get_c_name('*'),))
+prnt('}')
+prnt()
+
+# --
 # emitting the opcodes for individual types
 
 def _emit_bytecode_VoidType(self, tp, index):
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1484,3 +1484,14 @@
 assert (pt.x, pt.y) == (99*500*999, -99*500*999)
 pt = ptr_call2(ffi.addressof(lib, 'cb2'))
 assert (pt.x, pt.y) == (99*500*999, -99*500*999)
+
+def test_call_python_1():
+ffi = FFI()
+ffi.cdef("""
+CFFI_CALL_PYTHON int bar(int, int);
+CFFI_CALL_PYTHON void baz(int, int);
+CFFI_CALL_PYTHON int bok(void);
+CFFI_CALL_PYTHON void boz(void);
+""")
+lib = verify(ffi, 'test_call_p

[pypy-commit] pypy stmgc-c8: fix to allow showing loops again

2015-11-13 Thread Raemi
Author: Remi Meier 
Branch: stmgc-c8
Changeset: r80662:6612707f9f93
Date: 2015-11-13 13:19 +0100
http://bitbucket.org/pypy/pypy/changeset/6612707f9f93/

Log:fix to allow showing loops again

diff --git a/rpython/jit/metainterp/graphpage.py 
b/rpython/jit/metainterp/graphpage.py
--- a/rpython/jit/metainterp/graphpage.py
+++ b/rpython/jit/metainterp/graphpage.py
@@ -171,11 +171,13 @@
 op = operations[opindex]
 op_repr = op.repr(self.memo, graytext=True)
 if op.getopnum() == rop.DEBUG_MERGE_POINT:
-jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()]
-if jd_sd._get_printable_location_ptr:
-s = jd_sd.warmstate.get_location_str(op.getarglist()[3:])
-s = s.replace(',', '.') # we use comma for argument 
splitting
-op_repr = "debug_merge_point(%d, %d, '%s')" % 
(op.getarg(1).getint(), op.getarg(2).getint(), s)
+if self.metainterp_sd is not None:
+jd_sd = 
self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()]
+if jd_sd._get_printable_location_ptr:
+s = 
jd_sd.warmstate.get_location_str(op.getarglist()[3:])
+s = s.replace(',', '.') # we use comma for argument 
splitting
+op_repr = "debug_merge_point(%d, %d, '%s')" % 
(op.getarg(1).getint(),
+   
op.getarg(2).getint(), s)
 lines.append(op_repr)
 if is_interesting_guard(op):
 tgt = op.getdescr()._debug_suboperations[0]
diff --git a/rpython/jit/metainterp/history.py 
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -545,9 +545,6 @@
 self.name,
 ', '.join([box.repr(memo) for box in self.inputargs]))
 
-def get_display_text(self):# for graphpage.py
-return self.name + '\n' + repr(self.inputargs)
-
 def show(self, errmsg=None):
 "NOT_RPYTHON"
 from rpython.jit.metainterp.graphpage import display_procedures
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: fix

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2381:05685f1b6781
Date: 2015-11-13 13:19 +0100
http://bitbucket.org/cffi/cffi/changeset/05685f1b6781/

Log:fix

diff --git a/cffi/parse_c_type.h b/cffi/parse_c_type.h
--- a/cffi/parse_c_type.h
+++ b/cffi/parse_c_type.h
@@ -168,7 +168,7 @@
 void *reserved;
 };
 
-extern void _cffi_call_python(struct _cffi_callpy_s *, void *);
+extern void _cffi_call_python(struct _cffi_callpy_s *, char *);
 
 
 #ifdef _CFFI_INTERNAL
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1161,17 +1161,16 @@
 prnt()
 #
 # Write the implementation of the functions declared above
-for (tp, name), sig in zip(self._callpy, function_sigs):
-prnt('static %s' % sig)
+for j in range(len(self._callpy)):
+tp, name = self._callpy[j]
+prnt('static %s' % function_sigs[j])
 prnt('{')
 prnt('  uint64_t a[%d];' % max(len(tp.args), 1))
 prnt('  char *p = (char *)a;')
 for i, type in enumerate(tp.args):
 prnt('  *(%s)(p + %d) = a%d;' % (type.get_c_name('*'), i*8, i))
-prnt('  _cffi_call_python(_cffi_callpys + 0, a);')
-if isinstance(tp.result, model.VoidType):
-prnt('  (void)p;')
-else:
+prnt('  _cffi_call_python(_cffi_callpys + %d, p);' % j)
+if not isinstance(tp.result, model.VoidType):
 prnt('  return *(%s)p;' % (tp.result.get_c_name('*'),))
 prnt('}')
 prnt()
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: Pass and return structs

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2382:414c0306b311
Date: 2015-11-13 13:30 +0100
http://bitbucket.org/cffi/cffi/changeset/414c0306b311/

Log:Pass and return structs

diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1163,12 +1163,21 @@
 # Write the implementation of the functions declared above
 for j in range(len(self._callpy)):
 tp, name = self._callpy[j]
+size_of_a = max(len(tp.args), 1)
+if isinstance(tp.result, model.StructOrUnion):
+size_of_a = 'sizeof(%s) > %d ? (sizeof(%s) + 7) / 8 : %d' % (
+tp.result.get_c_name(''), 8 * size_of_a,
+tp.result.get_c_name(''), size_of_a)
 prnt('static %s' % function_sigs[j])
 prnt('{')
-prnt('  uint64_t a[%d];' % max(len(tp.args), 1))
+prnt('  uint64_t a[%s];' % size_of_a)
 prnt('  char *p = (char *)a;')
 for i, type in enumerate(tp.args):
-prnt('  *(%s)(p + %d) = a%d;' % (type.get_c_name('*'), i*8, i))
+arg = 'a%d' % i
+if isinstance(type, model.StructOrUnion):
+arg = '&' + arg
+type = model.PointerType(type)
+prnt('  *(%s)(p + %d) = %s;' % (type.get_c_name('*'), i*8, 
arg))
 prnt('  _cffi_call_python(_cffi_callpys + %d, p);' % j)
 if not isinstance(tp.result, model.VoidType):
 prnt('  return *(%s)p;' % (tp.result.get_c_name('*'),))
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1495,3 +1495,15 @@
 """)
 lib = verify(ffi, 'test_call_python_1', "")
 XXX
+
+def test_call_python_2():
+ffi = FFI()
+ffi.cdef("""
+struct foo_s { int a, b, c; };
+CFFI_CALL_PYTHON int bar(int, struct foo_s, int);
+CFFI_CALL_PYTHON struct foo_s baz(int, int);
+CFFI_CALL_PYTHON struct foo_s bok(void);
+""")
+lib = verify(ffi, 'test_call_python_2',
+ "struct foo_s { int a, b, c; };")
+XXX
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: 'long double' is the only primitive type that doesn't necessarily fit

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2383:b07d81267db0
Date: 2015-11-13 13:37 +0100
http://bitbucket.org/cffi/cffi/changeset/b07d81267db0/

Log:'long double' is the only primitive type that doesn't necessarily
fit inside uint64_t, for now

diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1161,9 +1161,14 @@
 prnt()
 #
 # Write the implementation of the functions declared above
+def may_need_128_bits(tp):
+return tp.name == 'long double'
+#
 for j in range(len(self._callpy)):
 tp, name = self._callpy[j]
 size_of_a = max(len(tp.args), 1)
+if may_need_128_bits(tp.result):
+size_of_a = max(size_of_a, 2)
 if isinstance(tp.result, model.StructOrUnion):
 size_of_a = 'sizeof(%s) > %d ? (sizeof(%s) + 7) / 8 : %d' % (
 tp.result.get_c_name(''), 8 * size_of_a,
@@ -1174,7 +1179,8 @@
 prnt('  char *p = (char *)a;')
 for i, type in enumerate(tp.args):
 arg = 'a%d' % i
-if isinstance(type, model.StructOrUnion):
+if (isinstance(type, model.StructOrUnion) or
+may_need_128_bits(type)):
 arg = '&' + arg
 type = model.PointerType(type)
 prnt('  *(%s)(p + %d) = %s;' % (type.get_c_name('*'), i*8, 
arg))
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1507,3 +1507,13 @@
 lib = verify(ffi, 'test_call_python_2',
  "struct foo_s { int a, b, c; };")
 XXX
+
+def test_call_python_3():
+ffi = FFI()
+ffi.cdef("""
+CFFI_CALL_PYTHON int bar(int, long double, int);
+CFFI_CALL_PYTHON long double baz(int, int);
+CFFI_CALL_PYTHON long double bok(void);
+""")
+lib = verify(ffi, 'test_call_python_3', "")
+XXX
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: fix

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2384:98e2f9e1ab1c
Date: 2015-11-13 13:43 +0100
http://bitbucket.org/cffi/cffi/changeset/98e2f9e1ab1c/

Log:fix

diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1162,7 +1162,8 @@
 #
 # Write the implementation of the functions declared above
 def may_need_128_bits(tp):
-return tp.name == 'long double'
+return (isinstance(tp, model.PrimitiveType) and
+tp.name == 'long double')
 #
 for j in range(len(self._callpy)):
 tp, name = self._callpy[j]
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Temporarily back out 3a7694159dfb until a solution is implemented to

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r80663:303dbcff1c35
Date: 2015-11-13 14:12 +0100
http://bitbucket.org/pypy/pypy/changeset/303dbcff1c35/

Log:Temporarily back out 3a7694159dfb until a solution is implemented to
avoid the many failures reported by buildbot.

diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -46,7 +46,7 @@
 """
 _pinned_objects.append(obj)
 return True
-
+
 
 class PinEntry(ExtRegistryEntry):
 _about_ = pin
@@ -533,8 +533,12 @@
 def _fetch_ffi():
 global _ffi_cache
 if _ffi_cache is None:
-import _cffi_backend
-_ffi_cache = _cffi_backend.FFI()
+try:
+import _cffi_backend
+_ffi_cache = _cffi_backend.FFI()
+except (ImportError, AttributeError):
+import py
+py.test.skip("need CFFI >= 1.0")
 return _ffi_cache
 
 @jit.dont_look_inside
@@ -812,7 +816,7 @@
 pending.extend(get_rpy_referents(gcref))
 
 all_typeids = {}
-
+
 def get_typeid(obj):
 raise Exception("does not work untranslated")
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: In this rewriting step, make a copy of the guard before mangling its

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r80664:e392b3d88ecf
Date: 2015-11-13 14:43 +0100
http://bitbucket.org/pypy/pypy/changeset/e392b3d88ecf/

Log:In this rewriting step, make a copy of the guard before mangling its
failargs. Avoids confusing log outputs.

diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -120,7 +120,9 @@
 # this case means between CALLs or unknown-size mallocs.
 #
 operations = self.remove_bridge_exception(operations)
+self._source_operations = operations
 for i in range(len(operations)):
+self._current_position = i
 op = operations[i]
 assert op.get_forwarded() is None
 if op.getopnum() == rop.DEBUG_MERGE_POINT:
@@ -211,7 +213,11 @@
 self.emit_op(op1)
 lst = op.getfailargs()[:]
 lst[i] = op1
-op.setfailargs(lst)
+operations = self._source_operations
+assert operations[self._current_position + 1] is op
+newop = op.copy_and_change(opnum)
+newop.setfailargs(lst)
+operations[self._current_position + 1] = newop
 
 # --
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: simplify

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2385:58b06aefb5a7
Date: 2015-11-13 13:49 +0100
http://bitbucket.org/cffi/cffi/changeset/58b06aefb5a7/

Log:simplify

diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1167,17 +1167,17 @@
 #
 for j in range(len(self._callpy)):
 tp, name = self._callpy[j]
-size_of_a = max(len(tp.args), 1)
+size_of_a = max(len(tp.args)*8, 8)
 if may_need_128_bits(tp.result):
-size_of_a = max(size_of_a, 2)
+size_of_a = max(size_of_a, 16)
 if isinstance(tp.result, model.StructOrUnion):
-size_of_a = 'sizeof(%s) > %d ? (sizeof(%s) + 7) / 8 : %d' % (
-tp.result.get_c_name(''), 8 * size_of_a,
+size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % (
+tp.result.get_c_name(''), size_of_a,
 tp.result.get_c_name(''), size_of_a)
 prnt('static %s' % function_sigs[j])
 prnt('{')
-prnt('  uint64_t a[%s];' % size_of_a)
-prnt('  char *p = (char *)a;')
+prnt('  char a[%s];' % size_of_a)
+prnt('  char *p = a;')
 for i, type in enumerate(tp.args):
 arg = 'a%d' % i
 if (isinstance(type, model.StructOrUnion) or
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: tweak tweak tweak until we can at least read the function pointer out of

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2386:716fcb19c96a
Date: 2015-11-13 15:34 +0100
http://bitbucket.org/cffi/cffi/changeset/716fcb19c96a/

Log:tweak tweak tweak until we can at least read the function pointer
out of the 'lib' object

diff --git a/c/lib_obj.c b/c/lib_obj.c
--- a/c/lib_obj.c
+++ b/c/lib_obj.c
@@ -364,6 +364,16 @@
 break;
 }
 
+case _CFFI_OP_CALL_PYTHON:
+/* for reading 'lib.bar' where bar is declared with CFFI_CALL_PYTHON */
+ct = realize_c_type(types_builder, types_builder->ctx.types,
+_CFFI_GETARG(g->type_op));
+if (ct == NULL)
+return NULL;
+x = convert_to_object(g->address, ct);
+Py_DECREF(ct);
+break;
+
 default:
 PyErr_Format(PyExc_NotImplementedError, "in lib_build_attr: op=%d",
  (int)_CFFI_GETOP(g->type_op));
diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h
--- a/cffi/_cffi_include.h
+++ b/cffi/_cffi_include.h
@@ -146,7 +146,9 @@
 ((Py_ssize_t(*)(CTypeDescrObject *, PyObject *, char **))_cffi_exports[23])
 #define _cffi_convert_array_from_object  \
 ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[24])
-#define _CFFI_NUM_EXPORTS 25
+#define _cffi_call_python\
+((void(*)(struct _cffi_callpy_s *, char *))_cffi_exports[25])
+#define _CFFI_NUM_EXPORTS 26
 
 typedef struct _ctypedescr CTypeDescrObject;
 
@@ -201,8 +203,10 @@
   the others follow */
 }
 
+/**  end CPython-specific section  **/
+#else
+extern void _cffi_call_python(struct _cffi_callpy_s *, char *);
 #endif
-/**  end CPython-specific section  **/
 
 
 #define _cffi_array_len(array)   (sizeof(array) / sizeof((array)[0]))
diff --git a/cffi/cffi_opcode.py b/cffi/cffi_opcode.py
--- a/cffi/cffi_opcode.py
+++ b/cffi/cffi_opcode.py
@@ -54,6 +54,7 @@
 OP_DLOPEN_FUNC = 35
 OP_DLOPEN_CONST= 37
 OP_GLOBAL_VAR_F= 39
+OP_CALL_PYTHON = 41
 
 PRIM_VOID  = 0
 PRIM_BOOL  = 1
diff --git a/cffi/parse_c_type.h b/cffi/parse_c_type.h
--- a/cffi/parse_c_type.h
+++ b/cffi/parse_c_type.h
@@ -27,6 +27,7 @@
 #define _CFFI_OP_DLOPEN_FUNC35
 #define _CFFI_OP_DLOPEN_CONST   37
 #define _CFFI_OP_GLOBAL_VAR_F   39
+#define _CFFI_OP_CALL_PYTHON41
 
 #define _CFFI_PRIM_VOID  0
 #define _CFFI_PRIM_BOOL  1
@@ -162,15 +163,11 @@
 
 struct _cffi_callpy_s {
 const char *name;
-const struct _cffi_type_context_s *ctx;
 int type_index;
-void *direct_fn;
-void *reserved;
+int reserved1;
+void *reserved2, *reserved3;
 };
 
-extern void _cffi_call_python(struct _cffi_callpy_s *, char *);
-
-
 #ifdef _CFFI_INTERNAL
 static int parse_c_type(struct _cffi_parse_info_s *info, const char *input);
 static int search_in_globals(const struct _cffi_type_context_s *ctx,
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -227,7 +227,6 @@
 self._lsts = {}
 for step_name in self.ALL_STEPS:
 self._lsts[step_name] = []
-self._callpy = []
 self._seen_struct_unions = set()
 self._generate("ctx")
 self._add_missing_struct_unions()
@@ -361,9 +360,6 @@
 prnt('};')
 prnt()
 #
-if self._callpy:
-self._generate_delayed_callpy()
-#
 # the init function
 base_module_name = self.module_name.split('.')[-1]
 prnt('#ifdef PYPY_VERSION')
@@ -1115,10 +,54 @@
 # CFFI_CALL_PYTHON
 
 def _generate_cpy_call_python_collecttype(self, tp, name):
-self._do_collect_type(tp.as_raw_function())
+assert isinstance(tp, model.FunctionPtrType)
+self._do_collect_type(tp)
 
 def _generate_cpy_call_python_decl(self, tp, name):
-pass# the function is delayed and only generated later
+prnt = self._prnt
+type_index = self._typesdict[tp.as_raw_function()]
+prnt('static struct _cffi_callpy_s _cffi_callpy__%s = { "%s", %d };' % 
(
+name, name, type_index))
+prnt()
+#
+arguments = []
+context = 'argument of %s' % name
+for i, type in enumerate(tp.args):
+arg = type.get_c_name(' a%d' % i, context)
+arguments.append(arg)
+#
+repr_arguments = ', '.join(arguments)
+repr_arguments = repr_arguments or 'void'
+name_and_arguments = '%s(%s)' % (name, repr_arguments)
+#
+def may_need_128_bits(tp):
+return (isinstance(tp, model.PrimitiveType) and
+tp.name == 'long double')
+#
+size_of_a = max(len(tp.args)*8, 8)
+if may_need_128_bits(tp.result):
+size_of_a = max(size_of_a, 16)
+if isinstance(tp.result, model.StructOrUnion):
+size

[pypy-commit] cffi static-callback: in-progress

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2387:9f653200584c
Date: 2015-11-13 15:55 +0100
http://bitbucket.org/cffi/cffi/changeset/9f653200584c/

Log:in-progress

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -6306,6 +6306,9 @@
 }
 #endif
 
+struct _cffi_callpy_s;  /* forward declaration */
+static void _cffi_call_python(struct _cffi_callpy_s *callpy, char *args);
+
 static void *cffi_exports[] = {
 NULL,
 _cffi_to_c_i8,
@@ -6337,6 +6340,7 @@
 _cffi_to_c__Bool,
 _prepare_pointer_call_argument,
 convert_array_from_object,
+_cffi_call_python,
 };
 
 static struct { const char *name; int value; } all_dlopen_flags[] = {
diff --git a/c/call_python.c b/c/call_python.c
new file mode 100644
--- /dev/null
+++ b/c/call_python.c
@@ -0,0 +1,6 @@
+
+
+static void _cffi_call_python(struct _cffi_callpy_s *callpy, char *args)
+{
+abort();
+}
diff --git a/c/cffi1_module.c b/c/cffi1_module.c
--- a/c/cffi1_module.c
+++ b/c/cffi1_module.c
@@ -16,6 +16,7 @@
 #include "lib_obj.c"
 #include "cdlopen.c"
 #include "commontypes.c"
+#include "call_python.c"
 
 
 static int init_ffi_lib(PyObject *m)
@@ -149,7 +150,7 @@
 PyObject *m, *modules_dict;
 FFIObject *ffi;
 LibObject *lib;
-Py_ssize_t version;
+Py_ssize_t version, num_exports;
 char *module_name, *exports, *module_name_with_lib;
 void **raw;
 const struct _cffi_type_context_s *ctx;
@@ -172,7 +173,10 @@
 }
 
 /* initialize the exports array */
-memcpy(exports, (char *)cffi_exports, sizeof(cffi_exports));
+num_exports = 25;
+if (ctx->flags & 1)/* set to mean "uses _cffi_call_python" */
+num_exports = 26;
+memcpy(exports, (char *)cffi_exports, num_exports * sizeof(void *));
 
 /* make the module object */
 m = _my_Py_InitModule(module_name);
diff --git a/c/lib_obj.c b/c/lib_obj.c
--- a/c/lib_obj.c
+++ b/c/lib_obj.c
@@ -370,7 +370,7 @@
 _CFFI_GETARG(g->type_op));
 if (ct == NULL)
 return NULL;
-x = convert_to_object(g->address, ct);
+x = convert_to_object((char *)&g->size_or_direct_fn, ct);
 Py_DECREF(ct);
 break;
 
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -118,6 +118,7 @@
 
 
 class Recompiler:
+_num_callpy = 0
 
 def __init__(self, ffi, module_name, target_is_python=False):
 self.ffi = ffi
@@ -356,7 +357,10 @@
 else:
 prnt('  NULL,  /* no includes */')
 prnt('  %d,  /* num_types */' % (len(self.cffi_types),))
-prnt('  0,  /* flags */')
+flags = 0
+if self._num_callpy:
+flags |= 1 # set to mean "uses _cffi_call_python"
+prnt('  %d,  /* flags */' % flags)
 prnt('};')
 prnt()
 #
@@ -1159,6 +1163,7 @@
 prnt('  return *(%s)p;' % (tp.result.get_c_name('*'),))
 prnt('}')
 prnt()
+self._num_callpy += 1
 
 def _generate_cpy_call_python_ctx(self, tp, name):
 if self.target_is_python:
@@ -1169,7 +1174,7 @@
 type_index = self._typesdict[tp]
 type_op = CffiOp(OP_CALL_PYTHON, type_index)
 self._lsts["global"].append(
-GlobalExpr(name, name, type_op, '&_cffi_callpy__%s' % name))
+GlobalExpr(name, '&_cffi_callpy__%s' % name, type_op, name))
 
 # --
 # emitting the opcodes for individual types
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1495,6 +1495,7 @@
 """)
 lib = verify(ffi, 'test_call_python_1', "")
 assert ffi.typeof(lib.bar) == ffi.typeof("int(*)(int, int)")
+lib.bar(4, 5)
 XXX
 
 def test_call_python_2():
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: translation fix

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r80665:1181ca147d11
Date: 2015-11-13 14:01 +
http://bitbucket.org/pypy/pypy/changeset/1181ca147d11/

Log:translation fix

diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py
--- a/pypy/module/cpyext/pystrtod.py
+++ b/pypy/module/cpyext/pystrtod.py
@@ -5,6 +5,7 @@
 from rpython.rlib import rdtoa
 from rpython.rlib import rfloat
 from rpython.rlib import rposix, jit
+from rpython.rlib.rarithmetic import intmask
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem import rffi
 
@@ -112,7 +113,9 @@
 NULL if the conversion failed. The caller is responsible for freeing the
 returned string by calling PyMem_Free().
 """
-buffer, rtype = rfloat.double_to_string(val, format_code, precision, flags)
+buffer, rtype = rfloat.double_to_string(val, format_code,
+intmask(precision),
+intmask(flags))
 if ptype != lltype.nullptr(rffi.INTP.TO):
 ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype])
 bufp = rffi.str2charp(buffer)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: in-progress

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2388:e8bfa0e0f9c6
Date: 2015-11-13 16:32 +0100
http://bitbucket.org/cffi/cffi/changeset/e8bfa0e0f9c6/

Log:in-progress

diff --git a/c/call_python.c b/c/call_python.c
--- a/c/call_python.c
+++ b/c/call_python.c
@@ -1,6 +1,51 @@
-
 
 static void _cffi_call_python(struct _cffi_callpy_s *callpy, char *args)
 {
+/* Invoked by the helpers generated from CFFI_CALL_PYTHON in the cdef.
+
+   'callpy' is a static structure that describes which of the
+   CFFI_CALL_PYTHON is called.  It has got fields 'name' and
+   'type_index' describing the function, and more reserved fields
+   that are initially zero.  These reserved fields are set up by
+   ffi.call_python(), which invokes init_call_python() below.
+
+   'args' is a pointer to an array of 8-byte entries.  Each entry
+   contains an argument.  If an argument is less than 8 bytes, only
+   the part at the beginning of the entry is initialized.  If an
+   argument is 'long double' or a struct/union, then it is passed
+   by reference.
+
+   'args' is also used as the place to write the result to.  In all
+   cases, 'args' is at least 8 bytes in size.
+*/
+save_errno();
+{
+#ifdef WITH_THREAD
+PyGILState_STATE state = PyGILState_Ensure();
+#endif
+const struct _cffi_type_context_s *ctx;
+ctx = (const struct _cffi_type_context_s *)callpy->reserved1;
+
+if (ctx == NULL) {
+/* uninitialized! */
+PyObject *f = PySys_GetObject("stderr");
+if (f != NULL) {
+PyFile_WriteString("CFFI_CALL_PYTHON: function ", f);
+PyFile_WriteString(callpy->name, f);
+PyFile_WriteString("() called, but no code was attached "
+   "to it yet with ffi.call_python('", f);
+PyFile_WriteString(callpy->name, f);
+PyFile_WriteString("').  Returning 0.\n", f);
+}
+memset(args, 0, callpy->size_of_result);
+return;
+}
+
 abort();
+
+#ifdef WITH_THREAD
+PyGILState_Release(state);
+#endif
+}
+restore_errno();
 }
diff --git a/cffi/parse_c_type.h b/cffi/parse_c_type.h
--- a/cffi/parse_c_type.h
+++ b/cffi/parse_c_type.h
@@ -164,8 +164,8 @@
 struct _cffi_callpy_s {
 const char *name;
 int type_index;
-int reserved1;
-void *reserved2, *reserved3;
+int size_of_result;
+void *reserved1, *reserved2;
 };
 
 #ifdef _CFFI_INTERNAL
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1121,8 +1121,14 @@
 def _generate_cpy_call_python_decl(self, tp, name):
 prnt = self._prnt
 type_index = self._typesdict[tp.as_raw_function()]
-prnt('static struct _cffi_callpy_s _cffi_callpy__%s = { "%s", %d };' % 
(
-name, name, type_index))
+if isinstance(tp.result, model.VoidType):
+size_of_result = '0'
+else:
+context = 'result of %s' % name
+size_of_result = '(int)sizeof(%s)' % (
+tp.result.get_c_name('', context),)
+prnt('static struct _cffi_callpy_s _cffi_callpy__%s =' % name)
+prnt('  { "%s", %d, %s };' % (name, type_index, size_of_result))
 prnt()
 #
 arguments = []
@@ -1146,8 +1152,7 @@
 size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % (
 tp.result.get_c_name(''), size_of_a,
 tp.result.get_c_name(''), size_of_a)
-context = 'result of %s' % name
-prnt('static %s' % tp.result.get_c_name(name_and_arguments, context))
+prnt('static %s' % tp.result.get_c_name(name_and_arguments))
 prnt('{')
 prnt('  char a[%s];' % size_of_a)
 prnt('  char *p = a;')
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: fix e392b3d88ecf: we must really not write back the modified operation

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r80666:c03930410323
Date: 2015-11-13 15:51 +
http://bitbucket.org/pypy/pypy/changeset/c03930410323/

Log:fix e392b3d88ecf: we must really not write back the modified
operation in any list, but just use it when building the _newops.

diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -120,13 +120,14 @@
 # this case means between CALLs or unknown-size mallocs.
 #
 operations = self.remove_bridge_exception(operations)
-self._source_operations = operations
+self._changed_op = None
 for i in range(len(operations)):
-self._current_position = i
 op = operations[i]
 assert op.get_forwarded() is None
 if op.getopnum() == rop.DEBUG_MERGE_POINT:
 continue
+if op is self._changed_op:
+op = self._changed_op_to
 # -- GETFIELD_GC --
 if op.getopnum() in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F,
  rop.GETFIELD_GC_R):
@@ -213,11 +214,10 @@
 self.emit_op(op1)
 lst = op.getfailargs()[:]
 lst[i] = op1
-operations = self._source_operations
-assert operations[self._current_position + 1] is op
 newop = op.copy_and_change(opnum)
 newop.setfailargs(lst)
-operations[self._current_position + 1] = newop
+self._changed_op = op
+self._changed_op_to = newop
 
 # --
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy faster-rstruct: introduce rawstorage.str_storage_getitem{, _unaligned}, which works as rawstorage.raw_storage_* but operates on RPython strings instead of raw buffers: since strings

2015-11-13 Thread antocuni
Author: Antonio Cuni 
Branch: faster-rstruct
Changeset: r80668:84c49eed1754
Date: 2015-05-15 22:38 +0200
http://bitbucket.org/pypy/pypy/changeset/84c49eed1754/

Log:introduce rawstorage.str_storage_getitem{,_unaligned}, which works
as rawstorage.raw_storage_* but operates on RPython strings instead
of raw buffers: since strings are immutable, we provide only the
functions for reading out of them, not writing

diff --git a/rpython/rlib/rawstorage.py b/rpython/rlib/rawstorage.py
--- a/rpython/rlib/rawstorage.py
+++ b/rpython/rlib/rawstorage.py
@@ -1,10 +1,13 @@
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, keepalive_until_here
 from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
 from rpython.annotator import model as annmodel
 from rpython.rtyper.llannotation import lltype_to_annotation
+from rpython.rlib import rgc
 from rpython.rlib.rgc import lltype_is_gc
 from rpython.rlib.objectmodel import specialize
+from rpython.rtyper.lltypesystem.rstr import STR, _get_raw_str_buf
+from rpython.rtyper.annlowlevel import llstr
 
 RAW_STORAGE = rffi.CCHARP.TO
 RAW_STORAGE_PTR = rffi.CCHARP
@@ -40,6 +43,29 @@
 def free_raw_storage(storage, track_allocation=True):
 lltype.free(storage, flavor='raw', track_allocation=track_allocation)
 
+
+@rgc.no_collect
+def str_storage_getitem(TP, s, index):
+lls = llstr(s)
+# from here, no GC operations can happen
+buf = _get_raw_str_buf(STR, lls, 0)
+storage = rffi.cast(RAW_STORAGE_PTR, buf)
+res = raw_storage_getitem(TP, storage, index)
+# end of "no GC" section
+keepalive_until_here(lls)
+return res
+
+@rgc.no_collect
+def str_storage_getitem_unaligned(TP, s, index):
+lls = llstr(s)
+# from here, no GC operations can happen
+buf = _get_raw_str_buf(STR, lls, 0)
+storage = rffi.cast(RAW_STORAGE_PTR, buf)
+res = raw_storage_getitem_unaligned(TP, storage, index)
+# end of "no GC" section
+keepalive_until_here(lls)
+return res
+
 # 
 #
 # Support for possibly-unaligned accesses
diff --git a/rpython/rlib/test/test_rawstorage.py 
b/rpython/rlib/test/test_rawstorage.py
--- a/rpython/rlib/test/test_rawstorage.py
+++ b/rpython/rlib/test/test_rawstorage.py
@@ -4,7 +4,8 @@
 from rpython.rlib import rawstorage
 from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage,\
  raw_storage_setitem, raw_storage_getitem, AlignmentError,\
- raw_storage_setitem_unaligned, raw_storage_getitem_unaligned
+ raw_storage_setitem_unaligned, raw_storage_getitem_unaligned,\
+ str_storage_getitem, str_storage_getitem_unaligned
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.translator.c.test.test_genc import compile
 
@@ -32,6 +33,26 @@
 assert res == 3.14
 free_raw_storage(r)
 
+def test_untranslated_str_storage():
+import struct
+buf = struct.pack('@lld', 42, 43, 123.0)
+size = struct.calcsize('@l')
+res = str_storage_getitem(lltype.Signed, buf, 0)
+assert res == 42
+res = str_storage_getitem(lltype.Signed, buf, size)
+assert res == 43
+res = str_storage_getitem(lltype.Float, buf, size*2)
+assert res == 123.0
+
+def test_untranslated_str_storage_unaligned(monkeypatch):
+import struct
+monkeypatch.setattr(rawstorage, 'misaligned_is_fine', False)
+buf = 'foo' + struct.pack('@ll', 42, 43)
+size = struct.calcsize('@l')
+res = str_storage_getitem_unaligned(lltype.Signed, buf, 3)
+assert res == 42
+res = str_storage_getitem_unaligned(lltype.Signed, buf, size+3)
+assert res == 43
 
 class TestRawStorage(BaseRtypingTest):
 
@@ -46,6 +67,21 @@
 x = self.interpret(f, [1<<30])
 assert x == 1 << 30
 
+def test_str_storage_int(self):
+import struct
+buf = struct.pack('@ll', 42, 43)
+size = struct.calcsize('@l')
+
+def f(i):
+res = str_storage_getitem(lltype.Signed, buf, i)
+return res
+
+x = self.interpret(f, [0])
+assert x == 42
+x = self.interpret(f, [8])
+assert x == 43
+
+
 def test_storage_float_unaligned(self, monkeypatch):
 def f(v):
 r = alloc_raw_storage(24)
diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -60,6 +60,13 @@
 @signature(types.any(), types.any(), types.int(), returns=types.any())
 @specialize.arg(0)
 def _get_raw_buf(TP, src, ofs):
+"""
+WARNING: dragons ahead.
+Return the address of the internal char* buffer of the low level
+string. The return value is valid as long as no GC operation occur, so
+you must ensure that it will be used inside a "GC safe" section, for
+example by mar

[pypy-commit] pypy faster-rstruct: a branch where to improve the performance of rstruct

2015-11-13 Thread antocuni
Author: Antonio Cuni 
Branch: faster-rstruct
Changeset: r80667:d9628e7cafa0
Date: 2015-11-13 17:20 +0100
http://bitbucket.org/pypy/pypy/changeset/d9628e7cafa0/

Log:a branch where to improve the performance of rstruct

___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy faster-rstruct: use the fast raw_storage way to read doubles and floats when rstruct is using native formats

2015-11-13 Thread antocuni
Author: Antonio Cuni 
Branch: faster-rstruct
Changeset: r80669:b790b4f590e3
Date: 2015-11-13 17:18 +0100
http://bitbucket.org/pypy/pypy/changeset/b790b4f590e3/

Log:use the fast raw_storage way to read doubles and floats when rstruct
is using native formats

diff --git a/rpython/rlib/rawstorage.py b/rpython/rlib/rawstorage.py
--- a/rpython/rlib/rawstorage.py
+++ b/rpython/rlib/rawstorage.py
@@ -45,6 +45,7 @@
 
 
 @rgc.no_collect
+@specialize.ll()
 def str_storage_getitem(TP, s, index):
 lls = llstr(s)
 # from here, no GC operations can happen
@@ -56,6 +57,7 @@
 return res
 
 @rgc.no_collect
+@specialize.ll()
 def str_storage_getitem_unaligned(TP, s, index):
 lls = llstr(s)
 # from here, no GC operations can happen
diff --git a/rpython/rlib/rstruct/nativefmttable.py 
b/rpython/rlib/rstruct/nativefmttable.py
--- a/rpython/rlib/rstruct/nativefmttable.py
+++ b/rpython/rlib/rstruct/nativefmttable.py
@@ -10,6 +10,7 @@
 from rpython.rlib.rstruct import standardfmttable as std
 from rpython.rlib.rstruct.error import StructError
 from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.rawstorage import str_storage_getitem
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper.tool import rffi_platform
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
@@ -27,9 +28,6 @@
 # 
 
 
-double_buf = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw', immortal=True)
-float_buf = lltype.malloc(rffi.FLOATP.TO, 1, flavor='raw', immortal=True)
-
 range_8_unroll = unrolling_iterable(list(reversed(range(8
 range_4_unroll = unrolling_iterable(list(reversed(range(4
 
@@ -48,10 +46,7 @@
 @specialize.argtype(0)
 def unpack_double(fmtiter):
 input = fmtiter.read(sizeof_double)
-p = rffi.cast(rffi.CCHARP, double_buf)
-for i in range(sizeof_double):
-p[i] = input[i]
-doubleval = double_buf[0]
+doubleval = str_storage_getitem(rffi.DOUBLE, input, 0)
 fmtiter.appendobj(doubleval)
 
 def pack_float(fmtiter):
@@ -71,11 +66,8 @@
 @specialize.argtype(0)
 def unpack_float(fmtiter):
 input = fmtiter.read(sizeof_float)
-p = rffi.cast(rffi.CCHARP, float_buf)
-for i in range(sizeof_float):
-p[i] = input[i]
-floatval = float_buf[0]
-doubleval = float(floatval)
+floatval = str_storage_getitem(rffi.FLOAT, input, 0)
+doubleval = float(floatval) # convert from r_singlefloat to rpython's float
 fmtiter.appendobj(doubleval)
 
 # 
diff --git a/rpython/rlib/rstruct/test/test_runpack.py 
b/rpython/rlib/rstruct/test/test_runpack.py
--- a/rpython/rlib/rstruct/test/test_runpack.py
+++ b/rpython/rlib/rstruct/test/test_runpack.py
@@ -37,3 +37,21 @@
 return runpack(">d", "testtest")
 assert fn() == struct.unpack(">d", "testtest")[0]
 assert self.interpret(fn, []) == struct.unpack(">d", "testtest")[0]
+
+def test_native_floats(self):
+"""
+Check the 'd' and 'f' format characters on native packing.
+"""
+d_data = struct.pack("d", 12.34)
+f_data = struct.pack("f", 12.34)
+def fn():
+d = runpack("@d", d_data)
+f = runpack("@f", f_data)
+return d, f
+#
+res = self.interpret(fn, [])
+d = res.item0
+f = res.item1  # convert from r_singlefloat
+assert d == 12.34 # no precision lost
+assert f != 12.34 # precision lost
+assert abs(f - 12.34) < 1E-6
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: passing test

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2389:7d025a85a48b
Date: 2015-11-13 16:35 +0100
http://bitbucket.org/cffi/cffi/changeset/7d025a85a48b/

Log:passing test

diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -4,6 +4,7 @@
 from cffi import recompiler
 from testing.udir import udir
 from testing.support import u
+from StringIO import StringIO
 
 
 def check_type_table(input, expected_output, included=None):
@@ -1495,8 +1496,16 @@
 """)
 lib = verify(ffi, 'test_call_python_1', "")
 assert ffi.typeof(lib.bar) == ffi.typeof("int(*)(int, int)")
-lib.bar(4, 5)
-XXX
+old_stderr = sys.stderr
+try:
+sys.stderr = f = StringIO()
+res = lib.bar(4, 5)
+finally:
+sys.stderr = old_stderr
+assert res == 0
+assert f.getvalue() == (
+"CFFI_CALL_PYTHON: function bar() called, but no code was attached "
+"to it yet with ffi.call_python('bar').  Returning 0.\n")
 
 def test_call_python_2():
 ffi = FFI()
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: ffi.call_python()

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2390:f1a86aeb8daf
Date: 2015-11-13 17:51 +0100
http://bitbucket.org/cffi/cffi/changeset/f1a86aeb8daf/

Log:ffi.call_python()

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4903,7 +4903,8 @@
 
 static int convert_from_object_fficallback(char *result,
CTypeDescrObject *ctype,
-   PyObject *pyobj)
+   PyObject *pyobj,
+   int encode_result_for_libffi)
 {
 /* work work work around a libffi irregularity: for integer return
types we have to fill at least a complete 'ffi_arg'-sized result
@@ -4919,6 +4920,8 @@
 return -1;
 }
 }
+if (!encode_result_for_libffi)
+goto skip;
 if (ctype->ct_flags & CT_PRIMITIVE_SIGNED) {
 PY_LONG_LONG value;
 /* It's probably fine to always zero-extend, but you never
@@ -4949,6 +4952,7 @@
 #endif
 }
 }
+ skip:
 return convert_from_object(result, ctype, pyobj);
 }
 
@@ -4983,14 +4987,9 @@
 Py_XDECREF(tb);
 }
 
-static void invoke_callback(ffi_cif *cif, void *result, void **args,
-void *userdata)
-{
-save_errno();
-{
-#ifdef WITH_THREAD
-PyGILState_STATE state = PyGILState_Ensure();
-#endif
+static void general_invoke_callback(int decode_args_from_libffi,
+void *result, char *args, void *userdata)
+{
 PyObject *cb_args = (PyObject *)userdata;
 CTypeDescrObject *ct = (CTypeDescrObject *)PyTuple_GET_ITEM(cb_args, 0);
 PyObject *signature = ct->ct_stuff;
@@ -5012,7 +5011,20 @@
 goto error;
 
 for (i=0; ict_flags & (CT_IS_LONGDOUBLE | CT_STRUCT | CT_UNION)) {
+abort();
+}
+}
+a = convert_to_object(a_src, a_ct);
 if (a == NULL)
 goto error;
 PyTuple_SET_ITEM(py_args, i, a);
@@ -5021,7 +5033,8 @@
 py_res = PyObject_Call(py_ob, py_args, NULL);
 if (py_res == NULL)
 goto error;
-if (convert_from_object_fficallback(result, SIGNATURE(1), py_res) < 0) {
+if (convert_from_object_fficallback(result, SIGNATURE(1), py_res,
+decode_args_from_libffi) < 0) {
 extra_error_line = "Trying to convert the result back to C:\n";
 goto error;
 }
@@ -5029,10 +5042,6 @@
 Py_XDECREF(py_args);
 Py_XDECREF(py_res);
 Py_DECREF(cb_args);
-#ifdef WITH_THREAD
-PyGILState_Release(state);
-#endif
-restore_errno();
 return;
 
  error:
@@ -5057,7 +5066,8 @@
 NULL);
 if (res1 != NULL) {
 if (res1 != Py_None)
-convert_from_object_fficallback(result, SIGNATURE(1), res1);
+convert_from_object_fficallback(result, SIGNATURE(1), res1,
+decode_args_from_libffi);
 Py_DECREF(res1);
 }
 if (!PyErr_Occurred()) {
@@ -5078,25 +5088,38 @@
 }
 }
 goto done;
-}
 
 #undef SIGNATURE
 }
 
-static PyObject *b_callback(PyObject *self, PyObject *args)
-{
-CTypeDescrObject *ct, *ctresult;
-CDataObject *cd;
-PyObject *ob, *error_ob = Py_None, *onerror_ob = Py_None;
-PyObject *py_rawerr, *infotuple = NULL;
-cif_description_t *cif_descr;
-ffi_closure *closure;
+static void invoke_callback(ffi_cif *cif, void *result, void **args,
+void *userdata)
+{
+save_errno();
+{
+#ifdef WITH_THREAD
+PyGILState_STATE state = PyGILState_Ensure();
+#endif
+
+general_invoke_callback(1, result, (char *)args, userdata);
+
+#ifdef WITH_THREAD
+PyGILState_Release(state);
+#endif
+}
+restore_errno();
+}
+
+static PyObject *prepare_callback_info_tuple(CTypeDescrObject *ct,
+ PyObject *ob,
+ PyObject *error_ob,
+ PyObject *onerror_ob,
+ int decode_args_from_libffi)
+{
+CTypeDescrObject *ctresult;
+PyObject *py_rawerr, *infotuple;
 Py_ssize_t size;
 
-if (!PyArg_ParseTuple(args, "O!O|OO:callback", &CTypeDescr_Type, &ct, &ob,
-  &error_ob, &onerror_ob))
-return NULL;
-
 if (!(ct->ct_flags & CT_FUNCTIONPTR)) {
 PyErr_Format(PyExc_TypeError, "expected a function ctype, got '%s'",
  ct->ct_name);
@@ -5125,13 +5148,31 @@
 memset(PyBytes_AS_STRING(py_rawerr), 0, size);
 if (error_ob != Py_None) {
 if (convert_from_object_fficallback(
-PyBytes_AS_STRING(py_rawerr), ctresult, error_ob) < 0) {
+PyBytes_AS_STRING(py_rawerr), ctresult, error_

[pypy-commit] cffi static-callback: More tests, make the name optional in ffi.call_python()

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2391:90daaaedaab6
Date: 2015-11-13 18:06 +0100
http://bitbucket.org/cffi/cffi/changeset/90daaaedaab6/

Log:More tests, make the name optional in ffi.call_python()

diff --git a/c/call_python.c b/c/call_python.c
--- a/c/call_python.c
+++ b/c/call_python.c
@@ -12,12 +12,20 @@
 CTypeDescrObject *ct;
 FFIObject *ffi;
 builder_c_t *types_builder;
+PyObject *name = NULL;
 
 if (!PyArg_ParseTuple(outer_args, "OzOO", &ffi, &s, &error, &onerror))
 return NULL;
 
 if (s == NULL) {
-abort();
+PyObject *name = PyObject_GetAttrString(fn, "__name__");
+if (name == NULL)
+return NULL;
+s = PyString_AsString(name);
+if (s == NULL) {
+Py_DECREF(name);
+return NULL;
+}
 }
 
 types_builder = &ffi->types_builder;
@@ -27,6 +35,7 @@
 g = &types_builder->ctx.globals[index];
 if (_CFFI_GETOP(g->type_op) != _CFFI_OP_CALL_PYTHON)
 goto not_found;
+Py_XDECREF(name);
 
 ct = realize_c_type(types_builder, types_builder->ctx.types,
 _CFFI_GETARG(g->type_op));
@@ -53,7 +62,9 @@
 return x;
 
  not_found:
-abort();
+PyErr_Format(FFIError, "ffi.call_python('%s'): name not found as a "
+   "CFFI_CALL_PYTHON line from the cdef", s);
+Py_XDECREF(name);
 return NULL;
 }
 
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1509,14 +1509,54 @@
 
 @ffi.call_python("bar")
 def my_bar(x, y):
-seen.append((x, y))
+seen.append(("Bar", x, y))
 return x * y
 assert my_bar == lib.bar
 seen = []
 res = lib.bar(6, 7)
-assert seen == [(6, 7)]
+assert seen == [("Bar", 6, 7)]
 assert res == 42
 
+@ffi.call_python()
+def baz(x, y):
+seen.append(("Baz", x, y))
+seen = []
+res = baz(50L, 8L)
+assert res is None
+assert seen == [("Baz", 50, 8)]
+assert type(seen[0][1]) is type(seen[0][2]) is int
+assert baz == lib.baz
+
+def test_call_python_bogus_name():
+ffi = FFI()
+ffi.cdef("int abc;")
+lib = verify(ffi, 'test_call_python_bogus_name', "int abc;")
+def fn():
+pass
+py.test.raises(ffi.error, ffi.call_python("unknown_name"), fn)
+py.test.raises(ffi.error, ffi.call_python("abc"), fn)
+assert lib.abc == 0
+e = py.test.raises(ffi.error, ffi.call_python("abc"), fn)
+assert str(e.value) == ("ffi.call_python('abc'): name not found as a "
+"CFFI_CALL_PYTHON line from the cdef")
+e = py.test.raises(ffi.error, ffi.call_python(), fn)
+assert str(e.value) == ("ffi.call_python('fn'): name not found as a "
+"CFFI_CALL_PYTHON line from the cdef")
+#
+py.test.raises(TypeError, ffi.call_python(42), fn)
+py.test.raises((TypeError, AttributeError), ffi.call_python(), "foo")
+class X:
+pass
+x = X()
+x.__name__ = x
+py.test.raises(TypeError, ffi.call_python(), x)
+
+def test_call_python_void_must_return_none():
+
+
+def test_call_python_redefine():
+
+
 def test_call_python_2():
 ffi = FFI()
 ffi.cdef("""
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: tests tests tests

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2393:2c51b78800b2
Date: 2015-11-13 18:23 +0100
http://bitbucket.org/cffi/cffi/changeset/2c51b78800b2/

Log:tests tests tests

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -5020,9 +5020,8 @@
 }
 else {
 a_src = args + i * 8;
-if (a_ct->ct_flags & (CT_IS_LONGDOUBLE | CT_STRUCT | CT_UNION)) {
-abort();
-}
+if (a_ct->ct_flags & (CT_IS_LONGDOUBLE | CT_STRUCT | CT_UNION))
+a_src = *(char **)a_src;
 }
 a = convert_to_object(a_src, a_ct);
 if (a == NULL)
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1573,7 +1573,8 @@
 def test_call_python_bogus_result_type():
 ffi = FFI()
 ffi.cdef("CFFI_CALL_PYTHON void bar(int);")
-lib = verify(ffi, 'test_call_python_void_must_return_none', "")
+lib = verify(ffi, 'test_call_python_bogus_result_type', "")
+#
 def bar(n):
 return n * 10
 bar1 = ffi.call_python()(bar)
@@ -1586,9 +1587,21 @@
 "TypeError: callback with the return type 'void' must return None\n")
 
 def test_call_python_redefine():
-
+ffi = FFI()
+ffi.cdef("CFFI_CALL_PYTHON int bar(int);")
+lib = verify(ffi, 'test_call_python_redefine', "")
+#
+@ffi.call_python()
+def bar(n):
+return n * 10
+assert lib.bar(42) == 420
+#
+@ffi.call_python()
+def bar(n):
+return -n
+assert lib.bar(42) == -42
 
-def test_call_python_2():
+def test_call_python_struct():
 ffi = FFI()
 ffi.cdef("""
 struct foo_s { int a, b, c; };
@@ -1596,16 +1609,56 @@
 CFFI_CALL_PYTHON struct foo_s baz(int, int);
 CFFI_CALL_PYTHON struct foo_s bok(void);
 """)
-lib = verify(ffi, 'test_call_python_2',
+lib = verify(ffi, 'test_call_python_struct',
  "struct foo_s { int a, b, c; };")
-XXX
+#
+@ffi.call_python()
+def bar(x, s, z):
+return x + s.a + s.b + s.c + z
+res = lib.bar(1000, [1001, 1002, 1004], 1008)
+assert res == 5015
+#
+@ffi.call_python()
+def baz(x, y):
+return [x + y, x - y, x * y]
+res = lib.baz(1000, 42)
+assert res.a == 1042
+assert res.b == 958
+assert res.c == 42000
+#
+@ffi.call_python()
+def bok():
+return [10, 20, 30]
+res = lib.bok()
+assert [res.a, res.b, res.c] == [10, 20, 30]
 
-def test_call_python_3():
+def test_call_python_long_double():
 ffi = FFI()
 ffi.cdef("""
 CFFI_CALL_PYTHON int bar(int, long double, int);
 CFFI_CALL_PYTHON long double baz(int, int);
 CFFI_CALL_PYTHON long double bok(void);
 """)
-lib = verify(ffi, 'test_call_python_3', "")
-XXX
+lib = verify(ffi, 'test_call_python_long_double', "")
+#
+@ffi.call_python()
+def bar(x, l, z):
+seen.append((x, l, z))
+return 6
+seen = []
+lib.bar(10, 3.5, 20)
+expected = ffi.cast("long double", 3.5)
+assert repr(seen) == repr([(10, expected, 20)])
+#
+@ffi.call_python()
+def baz(x, z):
+assert x == 10 and z == 20
+return expected
+res = lib.baz(10, 20)
+assert repr(res) == repr(expected)
+#
+@ffi.call_python()
+def bok():
+return expected
+res = lib.bok()
+assert repr(res) == repr(expected)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi static-callback: more tests

2015-11-13 Thread arigo
Author: Armin Rigo 
Branch: static-callback
Changeset: r2392:e1642fe0c4e6
Date: 2015-11-13 18:13 +0100
http://bitbucket.org/cffi/cffi/changeset/e1642fe0c4e6/

Log:more tests

diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1486,6 +1486,14 @@
 pt = ptr_call2(ffi.addressof(lib, 'cb2'))
 assert (pt.x, pt.y) == (99*500*999, -99*500*999)
 
+class StdErrCapture(object):
+def __enter__(self):
+self.old_stderr = sys.stderr
+sys.stderr = f = StringIO()
+return f
+def __exit__(self, *args):
+sys.stderr = self.old_stderr
+
 def test_call_python_1():
 ffi = FFI()
 ffi.cdef("""
@@ -1496,12 +1504,8 @@
 """)
 lib = verify(ffi, 'test_call_python_1', "")
 assert ffi.typeof(lib.bar) == ffi.typeof("int(*)(int, int)")
-old_stderr = sys.stderr
-try:
-sys.stderr = f = StringIO()
+with StdErrCapture() as f:
 res = lib.bar(4, 5)
-finally:
-sys.stderr = old_stderr
 assert res == 0
 assert f.getvalue() == (
 "CFFI_CALL_PYTHON: function bar() called, but no code was attached "
@@ -1527,6 +1531,21 @@
 assert type(seen[0][1]) is type(seen[0][2]) is int
 assert baz == lib.baz
 
+@ffi.call_python()
+def bok():
+seen.append("Bok")
+return 42
+seen = []
+assert lib.bok() == bok() == 42
+assert seen == ["Bok", "Bok"]
+
+@ffi.call_python()
+def boz():
+seen.append("Boz")
+seen = []
+assert lib.boz() is boz() is None
+assert seen == ["Boz", "Boz"]
+
 def test_call_python_bogus_name():
 ffi = FFI()
 ffi.cdef("int abc;")
@@ -1551,8 +1570,20 @@
 x.__name__ = x
 py.test.raises(TypeError, ffi.call_python(), x)
 
-def test_call_python_void_must_return_none():
-
+def test_call_python_bogus_result_type():
+ffi = FFI()
+ffi.cdef("CFFI_CALL_PYTHON void bar(int);")
+lib = verify(ffi, 'test_call_python_void_must_return_none', "")
+def bar(n):
+return n * 10
+bar1 = ffi.call_python()(bar)
+with StdErrCapture() as f:
+res = bar1(321)
+assert res is None
+assert f.getvalue() == (
+"From cffi callback %r:\n" % (bar,) +
+"Trying to convert the result back to C:\n"
+"TypeError: callback with the return type 'void' must return None\n")
 
 def test_call_python_redefine():
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy faster-rstruct: use the fast raw_storage unpacking also for integer types, when possible

2015-11-13 Thread antocuni
Author: Antonio Cuni 
Branch: faster-rstruct
Changeset: r80670:9972a7f270d5
Date: 2015-11-13 19:01 +0100
http://bitbucket.org/pypy/pypy/changeset/9972a7f270d5/

Log:use the fast raw_storage unpacking also for integer types, when
possible

diff --git a/rpython/rlib/rstruct/nativefmttable.py 
b/rpython/rlib/rstruct/nativefmttable.py
--- a/rpython/rlib/rstruct/nativefmttable.py
+++ b/rpython/rlib/rstruct/nativefmttable.py
@@ -8,6 +8,7 @@
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rarithmetic import r_singlefloat, widen
 from rpython.rlib.rstruct import standardfmttable as std
+from rpython.rlib.rstruct.standardfmttable import native_is_bigendian
 from rpython.rlib.rstruct.error import StructError
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.rawstorage import str_storage_getitem
@@ -16,8 +17,6 @@
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
 
-native_is_bigendian = struct.pack("=i", 1) == struct.pack(">i", 1)
-
 native_fmttable = {
 'x': std.standard_fmttable['x'],
 'c': std.standard_fmttable['c'],
diff --git a/rpython/rlib/rstruct/standardfmttable.py 
b/rpython/rlib/rstruct/standardfmttable.py
--- a/rpython/rlib/rstruct/standardfmttable.py
+++ b/rpython/rlib/rstruct/standardfmttable.py
@@ -12,7 +12,11 @@
 from rpython.rlib.rstruct import ieee
 from rpython.rlib.rstruct.error import StructError, StructOverflowError
 from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.rawstorage import str_storage_getitem
+from rpython.rlib import rarithmetic
+from rpython.rtyper.lltypesystem import rffi
 
+native_is_bigendian = struct.pack("=i", 1) == struct.pack(">i", 1)
 
 def pack_pad(fmtiter, count):
 fmtiter.result.append_multiple_char('\x00', count)
@@ -162,6 +166,15 @@
 
 # 
 
+def get_rffi_int_type(size, signed):
+for TYPE in rffi.platform.numbertype_to_rclass:
+if (rffi.sizeof(TYPE) == size and
+rarithmetic.is_signed_integer_type(TYPE) == signed):
+return TYPE
+raise KeyError("Cannot find an int type size=%d, signed=%d" % (size, 
signed))
+
+UNPACK_ALLOW_RAW_STORAGE = True
+
 def make_int_unpacker(size, signed, _memo={}):
 try:
 return _memo[size, signed]
@@ -180,13 +193,20 @@
 else:
 inttype = r_ulonglong
 unroll_range_size = unrolling_iterable(range(size))
+TYPE = get_rffi_int_type(size, signed)
 
 @specialize.argtype(0)
 def unpack_int(fmtiter):
 intvalue = inttype(0)
 s = fmtiter.read(size)
 idx = 0
-if fmtiter.bigendian:
+if UNPACK_ALLOW_RAW_STORAGE and fmtiter.bigendian == 
native_is_bigendian:
+# fast path, using the native raw_storage
+intvalue = str_storage_getitem(TYPE, s, 0)
+if not signed and size < native_int_size:
+intvalue = rarithmetic.intmask(intvalue)
+intvalue = inttype(intvalue)
+elif fmtiter.bigendian:
 for i in unroll_range_size:
 x = ord(s[idx])
 if signed and i == 0 and x >= 128:
diff --git a/rpython/rlib/rstruct/test/test_runpack.py 
b/rpython/rlib/rstruct/test/test_runpack.py
--- a/rpython/rlib/rstruct/test/test_runpack.py
+++ b/rpython/rlib/rstruct/test/test_runpack.py
@@ -1,5 +1,6 @@
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.rlib.rstruct.runpack import runpack
+from rpython.rlib.rstruct import standardfmttable
 from rpython.rlib.rarithmetic import LONG_BIT
 import struct
 
@@ -55,3 +56,37 @@
 assert d == 12.34 # no precision lost
 assert f != 12.34 # precision lost
 assert abs(f - 12.34) < 1E-6
+
+def test_unpack_standard_little(self):
+def unpack(fmt, data):
+def fn():
+return runpack(fmt, data)
+return self.interpret(fn, [])
+#
+assert unpack("i", 'ABCD') == 0x41424344
+assert unpack(">i", '\xff\xff\xff\xfd') == -3
+assert unpack(">i", '\x80\x00\x00\x00') == -2147483648
+assert unpack(">I", '\x81BCD') == 0x81424344
+assert unpack(">q", 'ABCDEFGH') == 0x4142434445464748
+assert unpack(">q", '\xbeMLKJIHH') == -0x41B2B3B4B5B6B7B8
+assert unpack(">Q", '\x81BCDEFGH') == 0x8142434445464748
+
+def test_unpack_standard_no_raw_storage(self, monkeypatch):
+monkeypatch.setattr(standardfmttable, 'UNPACK_ALLOW_RAW_STORAGE', 
False)
+self.test_unpack_standard_little()
+self.test_unpack_standard_big()
+
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy faster-rstruct: hg merge default

2015-11-13 Thread antocuni
Author: Antonio Cuni 
Branch: faster-rstruct
Changeset: r80671:ec2db01088b1
Date: 2015-11-14 02:08 +0100
http://bitbucket.org/pypy/pypy/changeset/ec2db01088b1/

Log:hg merge default

diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py
--- a/pypy/module/cpyext/pystrtod.py
+++ b/pypy/module/cpyext/pystrtod.py
@@ -5,6 +5,7 @@
 from rpython.rlib import rdtoa
 from rpython.rlib import rfloat
 from rpython.rlib import rposix, jit
+from rpython.rlib.rarithmetic import intmask
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem import rffi
 
@@ -112,7 +113,9 @@
 NULL if the conversion failed. The caller is responsible for freeing the
 returned string by calling PyMem_Free().
 """
-buffer, rtype = rfloat.double_to_string(val, format_code, precision, flags)
+buffer, rtype = rfloat.double_to_string(val, format_code,
+intmask(precision),
+intmask(flags))
 if ptype != lltype.nullptr(rffi.INTP.TO):
 ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype])
 bufp = rffi.str2charp(buffer)
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -120,13 +120,14 @@
 # this case means between CALLs or unknown-size mallocs.
 #
 operations = self.remove_bridge_exception(operations)
-self._source_operations = operations
+self._changed_op = None
 for i in range(len(operations)):
-self._current_position = i
 op = operations[i]
 assert op.get_forwarded() is None
 if op.getopnum() == rop.DEBUG_MERGE_POINT:
 continue
+if op is self._changed_op:
+op = self._changed_op_to
 # -- GETFIELD_GC --
 if op.getopnum() in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F,
  rop.GETFIELD_GC_R):
@@ -213,11 +214,10 @@
 self.emit_op(op1)
 lst = op.getfailargs()[:]
 lst[i] = op1
-operations = self._source_operations
-assert operations[self._current_position + 1] is op
 newop = op.copy_and_change(opnum)
 newop.setfailargs(lst)
-operations[self._current_position + 1] = newop
+self._changed_op = op
+self._changed_op_to = newop
 
 # --
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy exc-later: Reinstate the parts of specialize_exceptions() that add code branches.

2015-11-13 Thread rlamy
Author: Ronan Lamy 
Branch: exc-later
Changeset: r80672:5cdd77f61327
Date: 2015-11-13 20:04 +
http://bitbucket.org/pypy/pypy/changeset/5cdd77f61327/

Log:Reinstate the parts of specialize_exceptions() that add code
branches.

diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py
--- a/rpython/translator/simplify.py
+++ b/rpython/translator/simplify.py
@@ -311,6 +311,36 @@
 stack.extend(link.target.exits)
 seen[link.target] = True
 
+def propagate_uncaught_exceptions(graph):
+"""Add the equivalent of:
+except OverflowError:
+raise
+except Exception:
+raise
+to any try: except: suite that misses them."""
+for block in list(graph.iterblocks()):
+if block.canraise:
+op = block.raising_op
+exits = list(block.exits)
+if OverflowError in op.canraise:
+if not any(issubclass(OverflowError, exit.exitcase)
+   for exit in block.exits[1:]):
+v_etype = const(OverflowError)
+v_exc = Variable('last_exc_value')
+exit = Link([v_etype, v_exc], graph.exceptblock, 
OverflowError)
+exit.extravars(v_etype, v_exc)
+exits.append(exit)
+if Exception in op.canraise:
+if block.exits[-1].exitcase is not Exception:
+v_etype = Variable('last_exception')
+v_exc = Variable('last_exc_value')
+exit = Link([v_etype, v_exc], graph.exceptblock, Exception)
+exit.extravars(v_etype, v_exc)
+exits.append(exit)
+block.recloseblock(*exits)
+if len(exits) == 1:
+block.exitswitch = None
+
 
 def remove_assertion_errors(graph):
 """Remove branches that go directly to raising an AssertionError,
@@ -1053,6 +1083,7 @@
 transform_ovfcheck,
 simplify_exceptions,
 remove_assertion_errors,
+propagate_uncaught_exceptions,
 remove_dead_exceptions,
 join_blocks,
 ]
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit