[pypy-commit] pypy default: Remove get_display_text override
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)
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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()
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
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
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
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
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.
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