From pypy.commits at gmail.com Mon Apr 1 09:33:32 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 01 Apr 2019 06:33:32 -0700 (PDT) Subject: [pypy-commit] pypy default: package dlls needed for cffi-based modules in lib_pypy Message-ID: <5ca2132c.1c69fb81.897f9.2e9c@mx.google.com> Author: Matti Picus Branch: Changeset: r96391:da158a6f6a35 Date: 2019-04-01 15:39 +0300 http://bitbucket.org/pypy/pypy/changeset/da158a6f6a35/ Log: package dlls needed for cffi-based modules in lib_pypy diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -94,7 +94,7 @@ if sys.platform == 'win32' and not rename_pypy_c.lower().endswith('.exe'): rename_pypy_c += '.exe' - binaries = [(pypy_c, rename_pypy_c)] + binaries = [(pypy_c, rename_pypy_c, None)] if (sys.platform != 'win32' and # handled below not _fake and os.path.getsize(str(pypy_c)) < 500000): @@ -106,10 +106,12 @@ if not libpypy_c.check(): raise PyPyCNotFound('Expected pypy to be mostly in %r, but did ' 'not find it' % (str(libpypy_c),)) - binaries.append((libpypy_c, libpypy_name)) + binaries.append((libpypy_c, libpypy_name, None)) # builddir = py.path.local(options.builddir) pypydir = builddir.ensure(name, dir=True) + lib_pypy = pypydir.join('lib_pypy') + # do not create lib_pypy yet, it will be created by the copytree below includedir = basedir.join('include') shutil.copytree(str(includedir), str(pypydir.join('include'))) @@ -118,18 +120,18 @@ if sys.platform == 'win32': os.environ['PATH'] = str(basedir.join('externals').join('bin')) + ';' + \ os.environ.get('PATH', '') - src,tgt = binaries[0] + src, tgt, _ = binaries[0] pypyw = src.new(purebasename=src.purebasename + 'w') if pypyw.exists(): tgt = py.path.local(tgt) - binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 'w').basename)) + binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 'w').basename, None)) print "Picking %s" % str(pypyw) # Can't rename a DLL: it is always called 'libpypy-c.dll' - win_extras = ['libpypy-c.dll', 'sqlite3.dll'] + win_extras = [('libpypy-c.dll', None), ('sqlite3.dll', lib_pypy)] if not options.no_tk: - win_extras += ['tcl85.dll', 'tk85.dll'] + win_extras += [('tcl85.dll', lib_pypy), ('tk85.dll', lib_pypy)] - for extra in win_extras: + for extra,target_dir in win_extras: p = pypy_c.dirpath().join(extra) if not p.check(): p = py.path.local.sysfind(extra) @@ -137,7 +139,7 @@ print "%s not found, expect trouble if this is a shared build" % (extra,) continue print "Picking %s" % p - binaries.append((p, p.basename)) + binaries.append((p, p.basename, target_dir)) libsdir = basedir.join('libs') if libsdir.exists(): print 'Picking %s (and contents)' % libsdir @@ -169,7 +171,7 @@ raise MissingDependenciesError('Tk runtime') print '* Binaries:', [source.relto(str(basedir)) - for source, target in binaries] + for source, target, target_dir in binaries] # Careful: to copy lib_pypy, copying just the hg-tracked files # would not be enough: there are also ctypes_config_cache/_*_cache.py. @@ -177,15 +179,14 @@ shutil.copytree(str(basedir.join('lib-python').join(STDLIB_VER)), str(pypydir.join('lib-python').join(STDLIB_VER)), ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~')) - shutil.copytree(str(basedir.join('lib_pypy')), - str(pypydir.join('lib_pypy')), + shutil.copytree(str(basedir.join('lib_pypy')), str(lib_pypy), ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~', '*_cffi.c', '*.o')) for file in ['README.rst',]: shutil.copy(str(basedir.join(file)), str(pypydir)) for file in ['_testcapimodule.c', '_ctypes_test.c']: shutil.copyfile(str(basedir.join('lib_pypy', file)), - str(pypydir.join('lib_pypy', file))) + str(lib_pypy.join(file))) # Use original LICENCE file base_file = str(basedir.join('LICENSE')) with open(base_file) as fid: @@ -201,8 +202,11 @@ else: bindir = pypydir.join('bin') bindir.ensure(dir=True) - for source, target in binaries: - archive = bindir.join(target) + for source, target, target_dir in binaries: + if target_dir: + archive = target_dir.join(target) + else: + archive = bindir.join(target) if not _fake: shutil.copy(str(source), str(archive)) else: @@ -214,8 +218,12 @@ try: os.chdir(str(builddir)) if not _fake: - for source, target in binaries: - smartstrip(bindir.join(target), keep_debug=options.keep_debug) + for source, target, target_dir in binaries: + if target_dir: + archive = target_dir.join(target) + else: + archive = bindir.join(target) + smartstrip(archive, keep_debug=options.keep_debug) # if USE_ZIPFILE_MODULE: import zipfile From pypy.commits at gmail.com Mon Apr 1 09:39:32 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 01 Apr 2019 06:39:32 -0700 (PDT) Subject: [pypy-commit] pypy default: issue 2978 - print more dots to prevent timeout Message-ID: <5ca21494.1c69fb81.c1797.b859@mx.google.com> Author: Matti Picus Branch: Changeset: r96392:935dacab85cd Date: 2019-04-01 16:37 +0300 http://bitbucket.org/pypy/pypy/changeset/935dacab85cd/ Log: issue 2978 - print more dots to prevent timeout diff --git a/rpython/tool/algo/graphlib.py b/rpython/tool/algo/graphlib.py --- a/rpython/tool/algo/graphlib.py +++ b/rpython/tool/algo/graphlib.py @@ -6,8 +6,10 @@ 'edges' is a dict mapping vertices to a list of edges with its source. Note that we can usually use 'edges' as the set of 'vertices' too. """ +from rpython.tool.ansi_print import AnsiLogger from rpython.tool.identity_dict import identity_dict +log = AnsiLogger('graphlib') class Edge: def __init__(self, source, target): @@ -292,6 +294,7 @@ if root in roots_finished: continue cycles = all_cycles(root, v_depths, edges) + log.dot() if not cycles: roots_finished.add(root) continue From pypy.commits at gmail.com Mon Apr 1 11:50:01 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 08:50:01 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Move ts attribute to AbstractCPU Message-ID: <5ca23329.1c69fb81.3555d.9277@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96393:dc730d4211f1 Date: 2019-03-31 20:28 +0100 http://bitbucket.org/pypy/pypy/changeset/dc730d4211f1/ Log: Move ts attribute to AbstractCPU diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -36,7 +36,7 @@ # front-end will mutate them under our feet again. We also # need to make sure things get freed. _cache={} - + def mapping(box): if isinstance(box, Const) or box is None: return box @@ -208,7 +208,7 @@ class ArrayDescr(AbstractDescr): all_interiorfielddescrs = None - + def __init__(self, A, runner): self.A = self.OUTERA = A self._is_pure = A._immutable_field(None) @@ -322,7 +322,6 @@ class LLGraphCPU(model.AbstractCPU): - from rpython.jit.metainterp.typesystem import llhelper as ts supports_floats = True supports_longlong = r_uint is not r_ulonglong supports_singlefloats = True @@ -735,7 +734,7 @@ return rffi.LONGLONG else: raise NotImplementedError(size) - + def bh_gc_load_indexed_i(self, struct, index, scale, base_ofs, bytes): T = self._get_int_type_from_size(bytes) x = llop.gc_load_indexed(T, struct, index, scale, base_ofs) @@ -1089,7 +1088,7 @@ if box.datatype == INT: for i,a in enumerate(arg): if isinstance(a, bool): - arg[i] = int(a) + arg[i] = int(a) assert all([lltype.typeOf(a) == lltype.Signed for a in arg]) elif box.datatype == FLOAT: assert all([lltype.typeOf(a) == longlong.FLOATSTORAGE or \ diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -23,8 +23,6 @@ class AbstractLLCPU(AbstractCPU): - from rpython.jit.metainterp.typesystem import llhelper as ts - HAS_CODEMAP = False done_with_this_frame_descr_int = None # overridden by pyjitpl.py diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -9,6 +9,8 @@ total_freed_bridges = 0 class AbstractCPU(object): + from rpython.jit.metainterp.typesystem import llhelper as ts + supports_floats = False supports_longlong = False # ^^^ This is only useful on 32-bit platforms. If True, diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -730,7 +730,7 @@ else: from rpython.jit.metainterp.blackhole import resume_in_blackhole if isinstance(self, ResumeGuardCopiedDescr): - resume_in_blackhole(metainterp_sd, jitdriver_sd, self.prev, deadframe) + resume_in_blackhole(metainterp_sd, jitdriver_sd, self.prev, deadframe) else: assert isinstance(self, ResumeGuardDescr) resume_in_blackhole(metainterp_sd, jitdriver_sd, self, deadframe) @@ -921,7 +921,7 @@ cloned.copy_all_attributes_from(self) return cloned -class AllVirtuals: +class AllVirtuals(object): llopaque = True cache = None diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py --- a/rpython/jit/metainterp/logger.py +++ b/rpython/jit/metainterp/logger.py @@ -1,4 +1,4 @@ -from rpython.jit.metainterp.history import ConstInt, ConstFloat +from rpython.jit.metainterp.history import ConstInt, ConstFloat, ConstPtr from rpython.jit.metainterp.resoperation import rop, AbstractInputArg from rpython.rlib.debug import (have_debug_prints, debug_start, debug_stop, debug_print) @@ -135,7 +135,6 @@ """ def __init__(self, metainterp_sd, guard_number, memo): self.metainterp_sd = metainterp_sd - self.ts = metainterp_sd.cpu.ts self.guard_number = guard_number if memo is None: memo = {} @@ -157,7 +156,7 @@ if name: return 'ConstClass(' + name + ')' return str(arg.value) - elif isinstance(arg, self.ts.ConstRef): + elif isinstance(arg, ConstPtr): if arg.value: return 'ConstPtr(ptr' + str(mv) + ')' return 'ConstPtr(null)' diff --git a/rpython/jit/metainterp/test/test_compile.py b/rpython/jit/metainterp/test/test_compile.py --- a/rpython/jit/metainterp/test/test_compile.py +++ b/rpython/jit/metainterp/test/test_compile.py @@ -12,16 +12,17 @@ class FakeCPU(object): supports_guard_gc_type = True - + class Storage: pass - + class tracker: pass ts = typesystem.llhelper def __init__(self): self.seen = [] + def compile_loop(self, inputargs, operations, token, jd_id=0, unique_id=0, log=True, name='', logger=None): diff --git a/rpython/jit/metainterp/test/test_logger.py b/rpython/jit/metainterp/test/test_logger.py --- a/rpython/jit/metainterp/test/test_logger.py +++ b/rpython/jit/metainterp/test/test_logger.py @@ -1,12 +1,11 @@ - import re +from StringIO import StringIO from rpython.rlib import debug from rpython.jit.tool.oparser import pure_parse from rpython.jit.metainterp import logger -from rpython.jit.metainterp.typesystem import llhelper -from StringIO import StringIO from rpython.jit.metainterp.optimizeopt.util import equaloplists -from rpython.jit.metainterp.history import AbstractDescr, JitCellToken, BasicFailDescr, BasicFinalDescr +from rpython.jit.metainterp.history import ( + AbstractDescr, JitCellToken, BasicFailDescr, BasicFinalDescr) from rpython.jit.backend.model import AbstractCPU @@ -50,8 +49,6 @@ return logops class TestLogger(object): - ts = llhelper - def make_metainterp_sd(self): class FakeJitDriver(object): class warmstate(object): @@ -59,7 +56,6 @@ class FakeMetaInterpSd: cpu = AbstractCPU() - cpu.ts = self.ts jitdrivers_sd = [FakeJitDriver()] def get_name_from_address(self, addr): return 'Name' diff --git a/rpython/rlib/rjitlog/rjitlog.py b/rpython/rlib/rjitlog/rjitlog.py --- a/rpython/rlib/rjitlog/rjitlog.py +++ b/rpython/rlib/rjitlog/rjitlog.py @@ -11,7 +11,7 @@ from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.jit.metainterp import resoperation as resoperations from rpython.jit.metainterp.resoperation import rop -from rpython.jit.metainterp.history import ConstInt, ConstFloat +from rpython.jit.metainterp.history import ConstInt, ConstFloat, ConstPtr from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import r_longlong from rpython.rtyper.lltypesystem import lltype, llmemory, rffi @@ -455,9 +455,6 @@ def __init__(self, tag, memo, metainterp_sd, mc, logger): self.memo = memo self.metainterp_sd = metainterp_sd - self.ts = None - if self.metainterp_sd is not None: - self.ts = metainterp_sd.cpu.ts self.tag = tag self.mc = mc self.logger = logger @@ -625,7 +622,7 @@ if name: return 'ConstClass(' + name + ')' return str(arg.value) - elif self.ts is not None and isinstance(arg, self.ts.ConstRef): + elif isinstance(arg, ConstPtr): if arg.value: return 'ConstPtr(ptr' + str(mv) + ')' return 'ConstPtr(null)' diff --git a/rpython/rlib/rjitlog/test/test_jitlog.py b/rpython/rlib/rjitlog/test/test_jitlog.py --- a/rpython/rlib/rjitlog/test/test_jitlog.py +++ b/rpython/rlib/rjitlog/test/test_jitlog.py @@ -42,7 +42,6 @@ class FakeMetaInterpSd: cpu = AbstractCPU() - cpu.ts = None jitdrivers_sd = [FakeJitDriver()] def get_name_from_address(self, addr): return 'Name' From pypy.commits at gmail.com Mon Apr 1 11:50:03 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 08:50:03 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Remove ConstRef, NULLREF, CONST_NULL from llhelper Message-ID: <5ca2332b.1c69fb81.48e18.92a1@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96394:f0523017b3da Date: 2019-04-01 03:52 +0100 http://bitbucket.org/pypy/pypy/changeset/f0523017b3da/ Log: Remove ConstRef, NULLREF, CONST_NULL from llhelper 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 @@ -186,8 +186,6 @@ else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) - elif kind == "ref": - return cpu.ts.new_ConstRef(x) elif kind == "float": return ConstFloat(longlong.getfloatstorage(x)) else: @@ -716,7 +714,7 @@ @specialize.argtype(2) def set_op_value(self, op, value): if value is None: - return + return elif isinstance(value, bool): op.setint(int(value)) elif lltype.typeOf(value) == lltype.Signed: diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py b/rpython/jit/metainterp/optimizeopt/bridgeopt.py --- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py +++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py @@ -2,6 +2,7 @@ optimizer of the bridge attached to a guard. """ from rpython.jit.metainterp import resumecode +from rpython.jit.metainterp.history import Const, ConstInt, CONST_NULL # adds the following sections at the end of the resume code: @@ -34,7 +35,6 @@ # maybe should be delegated to the optimization classes? def tag_box(box, liveboxes_from_env, memo): - from rpython.jit.metainterp.history import Const if isinstance(box, Const): return memo.getconst(box) else: @@ -43,13 +43,12 @@ def decode_box(resumestorage, tagged, liveboxes, cpu): from rpython.jit.metainterp.resume import untag, TAGCONST, TAGINT, TAGBOX from rpython.jit.metainterp.resume import NULLREF, TAG_CONST_OFFSET, tagged_eq - from rpython.jit.metainterp.history import ConstInt num, tag = untag(tagged) # NB: the TAGVIRTUAL case can't happen here, because this code runs after # virtuals are already forced again if tag == TAGCONST: if tagged_eq(tagged, NULLREF): - box = cpu.ts.CONST_NULL + box = CONST_NULL else: box = resumestorage.rd_consts[num - TAG_CONST_OFFSET] elif tag == TAGINT: @@ -61,7 +60,6 @@ return box def serialize_optimizer_knowledge(optimizer, numb_state, liveboxes, liveboxes_from_env, memo): - from rpython.jit.metainterp.history import ConstInt available_boxes = {} for box in liveboxes: if box is not None and box in liveboxes_from_env: @@ -124,7 +122,6 @@ numb_state.append_int(0) def deserialize_optimizer_knowledge(optimizer, resumestorage, frontend_boxes, liveboxes): - from rpython.jit.metainterp.history import ConstInt reader = resumecode.Reader(resumestorage.rd_numb) assert len(frontend_boxes) == len(liveboxes) metainterp_sd = optimizer.metainterp_sd diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -1,6 +1,7 @@ from rpython.jit.metainterp import jitprof, resume, compile from rpython.jit.metainterp.executor import execute_nonspec_const -from rpython.jit.metainterp.history import Const, ConstInt, ConstPtr +from rpython.jit.metainterp.history import ( + Const, ConstInt, ConstPtr, CONST_NULL) from rpython.jit.metainterp.optimizeopt.intutils import IntBound,\ ConstIntBound, MININT, MAXINT, IntUnbounded from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method @@ -21,7 +22,6 @@ CONST_0 = ConstInt(0) CONST_1 = ConstInt(1) CONST_ZERO_FLOAT = Const._new(0.0) -llhelper.CONST_NULLREF = llhelper.CONST_NULL REMOVED = AbstractResOp() class LoopInfo(object): @@ -158,7 +158,7 @@ if isinstance(fw, info.AbstractRawPtrInfo): return True return False - + def getrawptrinfo(self, op, create=False, is_object=False): assert op.type == 'i' op = self.get_box_replacement(op) @@ -464,7 +464,7 @@ def make_nonnull_str(self, op, mode): from rpython.jit.metainterp.optimizeopt import vstring - + op = self.get_box_replacement(op) if op.is_constant(): return @@ -475,7 +475,7 @@ def ensure_ptr_info_arg0(self, op): from rpython.jit.metainterp.optimizeopt import vstring - + arg0 = self.get_box_replacement(op.getarg(0)) if arg0.is_constant(): return info.ConstPtrInfo(arg0) @@ -503,7 +503,7 @@ elif opnum in (rop.GUARD_CLASS, rop.GUARD_NONNULL_CLASS): opinfo = info.InstancePtrInfo() elif opnum in (rop.STRLEN,): - opinfo = vstring.StrPtrInfo(vstring.mode_string) + opinfo = vstring.StrPtrInfo(vstring.mode_string) elif opnum in (rop.UNICODELEN,): opinfo = vstring.StrPtrInfo(vstring.mode_unicode) else: @@ -515,7 +515,7 @@ def new_const(self, fieldofs): if fieldofs.is_pointer_field(): - return self.cpu.ts.CONST_NULL + return CONST_NULL elif fieldofs.is_float_field(): return CONST_ZERO_FLOAT else: @@ -523,7 +523,7 @@ def new_const_item(self, arraydescr): if arraydescr.is_array_of_pointers(): - return self.cpu.ts.CONST_NULL + return CONST_NULL elif arraydescr.is_array_of_floats(): return CONST_ZERO_FLOAT else: diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,8 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.codewriter import longlong from rpython.jit.metainterp import compile -from rpython.jit.metainterp.history import (Const, ConstInt, make_hashable_int, - ConstFloat) +from rpython.jit.metainterp.history import ( + Const, ConstInt, make_hashable_int, ConstFloat, CONST_NULL) from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.optimizeopt.intutils import IntBound from rpython.jit.metainterp.optimizeopt.optimizer import ( @@ -354,7 +354,7 @@ return self.emit(op) def postprocess_GUARD_ISNULL(self, op): - self.make_constant(op.getarg(0), self.optimizer.cpu.ts.CONST_NULL) + self.make_constant(op.getarg(0), CONST_NULL) def optimize_GUARD_IS_OBJECT(self, op): info = self.getptrinfo(op.getarg(0)) diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py --- a/rpython/jit/metainterp/optimizeopt/virtualize.py +++ b/rpython/jit/metainterp/optimizeopt/virtualize.py @@ -122,8 +122,7 @@ newop.set_forwarded(vrefvalue) token = ResOperation(rop.FORCE_TOKEN, []) vrefvalue.setfield(descr_virtual_token, newop, token) - vrefvalue.setfield(descr_forced, newop, - self.optimizer.cpu.ts.CONST_NULLREF) + vrefvalue.setfield(descr_forced, newop, CONST_NULL) return self.emit(token) def optimize_VIRTUAL_REF_FINISH(self, op): diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py --- a/rpython/jit/metainterp/optimizeopt/vstring.py +++ b/rpython/jit/metainterp/optimizeopt/vstring.py @@ -1,7 +1,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.history import (Const, ConstInt, ConstPtr, get_const_ptr_for_string, get_const_ptr_for_unicode, REF, INT, - DONT_CHANGE) + DONT_CHANGE, CONST_NULL) from rpython.jit.metainterp.optimizeopt import optimizer from rpython.jit.metainterp.optimizeopt.optimizer import CONST_0, CONST_1 from rpython.jit.metainterp.optimizeopt.optimizer import llhelper, REMOVED @@ -140,12 +140,12 @@ srcbox = self.force_box(op, string_optimizer) return copy_str_content(string_optimizer, srcbox, targetbox, CONST_0, offsetbox, lengthbox, mode) - + class VStringPlainInfo(StrPtrInfo): #_attrs_ = ('mode', '_is_virtual') _chars = None - + def __init__(self, mode, is_virtual, length): if length != -1: self._chars = [None] * length @@ -218,7 +218,7 @@ start = None lgtop = None s = None - + def __init__(self, s, start, length, mode): self.s = s self.start = start @@ -271,7 +271,7 @@ vleft = None vright = None _is_virtual = False - + def __init__(self, mode, vleft, vright, is_virtual): self.vleft = vleft self.vright = vright @@ -785,9 +785,8 @@ if i1 and i1.is_null(): self.make_constant(resultop, CONST_1) return True, None - op = self.optimizer.replace_op_with(resultop, rop.PTR_EQ, - [arg1, llhelper.CONST_NULL], - descr=DONT_CHANGE) + op = self.optimizer.replace_op_with( + resultop, rop.PTR_EQ, [arg1, CONST_NULL], descr=DONT_CHANGE) return True, self.emit(op) # return False, None diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -8,7 +8,7 @@ from rpython.jit.metainterp import history, compile, resume, executor, jitexc from rpython.jit.metainterp.heapcache import HeapCache from rpython.jit.metainterp.history import (Const, ConstInt, ConstPtr, - ConstFloat, TargetToken, MissingValue, SwitchToBlackhole) + ConstFloat, CONST_NULL, TargetToken, MissingValue, SwitchToBlackhole) from rpython.jit.metainterp.jitprof import EmptyProfiler from rpython.jit.metainterp.logger import Logger from rpython.jit.metainterp.optimizeopt.util import args_dict @@ -136,9 +136,12 @@ # is not defined yet. argcode = self._result_argcode index = ord(self.bytecode[self.pc - 1]) - if argcode == 'i': self.registers_i[index] = history.CONST_FALSE - elif argcode == 'r': self.registers_r[index] = history.CONST_NULL - elif argcode == 'f': self.registers_f[index] = history.CONST_FZERO + if argcode == 'i': + self.registers_i[index] = history.CONST_FALSE + elif argcode == 'r': + self.registers_r[index] = CONST_NULL + elif argcode == 'f': + self.registers_f[index] = history.CONST_FZERO self._result_argcode = '?' # done # info = self.get_current_position_info() @@ -269,11 +272,11 @@ @arguments("box") def opimpl_ptr_nonzero(self, box): - return self.execute(rop.PTR_NE, box, history.CONST_NULL) + return self.execute(rop.PTR_NE, box, CONST_NULL) @arguments("box") def opimpl_ptr_iszero(self, box): - return self.execute(rop.PTR_EQ, box, history.CONST_NULL) + return self.execute(rop.PTR_EQ, box, CONST_NULL) @arguments("box") def opimpl_assert_not_none(self, box): @@ -931,8 +934,7 @@ token_descr = vinfo.vable_token_descr mi = self.metainterp tokenbox = mi.execute_and_record(rop.GETFIELD_GC_R, token_descr, box) - condbox = mi.execute_and_record(rop.PTR_NE, None, tokenbox, - history.CONST_NULL) + condbox = mi.execute_and_record(rop.PTR_NE, None, tokenbox, CONST_NULL) funcbox = ConstInt(rffi.cast(lltype.Signed, vinfo.clear_vable_ptr)) calldescr = vinfo.clear_vable_descr self.execute_varargs(rop.COND_CALL, [condbox, funcbox, box], @@ -1495,7 +1497,7 @@ vref = vrefbox.getref_base() if vrefinfo.is_virtual_ref(vref): # XXX write a comment about nullbox - nullbox = self.metainterp.cpu.ts.CONST_NULL + nullbox = CONST_NULL metainterp.history.record(rop.VIRTUAL_REF_FINISH, [vrefbox, nullbox], None) @@ -2957,7 +2959,7 @@ # CALL_xxx is recorded self.history.record(rop.VIRTUAL_REF_FINISH, [vrefbox, virtualbox], None) # mark this situation by replacing the vrefbox with ConstPtr(NULL) - self.virtualref_boxes[i+1] = self.cpu.ts.CONST_NULL + self.virtualref_boxes[i+1] = CONST_NULL def handle_possible_exception(self): if self.last_exc_value: @@ -3075,7 +3077,7 @@ abox, ConstInt(j), itembox) assert i + 1 == len(self.virtualizable_boxes) # we're during tracing, so we should not execute it - self.history.record(rop.SETFIELD_GC, [vbox, self.cpu.ts.CONST_NULL], + self.history.record(rop.SETFIELD_GC, [vbox, CONST_NULL], None, descr=vinfo.vable_token_descr) def replace_box(self, oldbox, newbox): diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py --- a/rpython/jit/metainterp/quasiimmut.py +++ b/rpython/jit/metainterp/quasiimmut.py @@ -42,7 +42,7 @@ def do_force_quasi_immutable(cpu, p, mutatefielddescr): qmut_ref = cpu.bh_getfield_gc_r(p, mutatefielddescr) if qmut_ref: - cpu.bh_setfield_gc_r(p, cpu.ts.NULLREF, mutatefielddescr) + cpu.bh_setfield_gc_r(p, ConstPtr.value, mutatefielddescr) qmut_ptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, qmut_ref) qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr) qmut.invalidate() @@ -109,7 +109,7 @@ # fields struct = lltype.nullptr(llmemory.GCREF.TO) fielddescr = None - + def __init__(self, cpu, struct, fielddescr, mutatefielddescr): self.cpu = cpu self.struct = struct diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -1,8 +1,8 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp import jitprof -from rpython.jit.metainterp.history import (Const, ConstInt, getkind, - INT, REF, FLOAT, AbstractDescr, IntFrontendOp, RefFrontendOp, - FloatFrontendOp) +from rpython.jit.metainterp.history import ( + Const, ConstInt, ConstPtr, getkind, INT, REF, FLOAT, CONST_NULL, + AbstractDescr, IntFrontendOp, RefFrontendOp, FloatFrontendOp) from rpython.jit.metainterp.resoperation import rop from rpython.rlib import rarithmetic, rstack from rpython.rlib.objectmodel import (we_are_translated, specialize, @@ -241,7 +241,7 @@ is_virtual = (info is not None and info.is_virtual()) if box.type == 'i': info = optimizer.getrawptrinfo(box, create=False) - is_virtual = (info is not None and info.is_virtual()) + is_virtual = (info is not None and info.is_virtual()) if is_virtual: tagged = tag(num_virtuals, TAGVIRTUAL) num_virtuals += 1 @@ -471,7 +471,7 @@ def _number_virtuals(self, liveboxes, optimizer, num_env_virtuals): from rpython.jit.metainterp.optimizeopt.info import AbstractVirtualPtrInfo - + # !! 'liveboxes' is a list that is extend()ed in-place !! memo = self.memo new_liveboxes = [None] * memo.num_cached_boxes() @@ -1251,7 +1251,7 @@ num, tag = untag(tagged) if tag == TAGCONST: if tagged_eq(tagged, NULLREF): - box = self.cpu.ts.CONST_NULL + box = CONST_NULL else: box = self.consts[num - TAG_CONST_OFFSET] elif tag == TAGVIRTUAL: @@ -1569,7 +1569,7 @@ num, tag = untag(tagged) if tag == TAGCONST: if tagged_eq(tagged, NULLREF): - return self.cpu.ts.NULLREF + return ConstPtr.value return self.consts[num - TAG_CONST_OFFSET].getref_base() elif tag == TAGVIRTUAL: return self.getvirtual_ptr(num) diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py --- a/rpython/jit/metainterp/test/test_resume.py +++ b/rpython/jit/metainterp/test/test_resume.py @@ -2,31 +2,30 @@ import py import sys from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.jit.metainterp.resume import ResumeDataVirtualAdder,\ - AbstractResumeDataReader, get_VirtualCache_class, ResumeDataBoxReader,\ - tag, TagOverflow, untag, tagged_eq, UNASSIGNED, TAGBOX, TAGVIRTUAL,\ - tagged_list_eq, AbstractVirtualInfo, TAGCONST, NULLREF,\ - ResumeDataDirectReader, TAGINT, REF, VirtualInfo, VStructInfo,\ - VArrayInfoNotClear, VStrPlainInfo, VStrConcatInfo, VStrSliceInfo,\ - VUniPlainInfo, VUniConcatInfo, VUniSliceInfo,\ - capture_resumedata, ResumeDataLoopMemo, UNASSIGNEDVIRTUAL, INT,\ - annlowlevel, PENDINGFIELDSP, TAG_CONST_OFFSET -from rpython.jit.metainterp.resumecode import unpack_numbering,\ - create_numbering, NULL_NUMBER -from rpython.jit.metainterp.opencoder import Trace, Snapshot, TopSnapshot +from rpython.jit.metainterp.resume import ( + ResumeDataVirtualAdder, AbstractResumeDataReader, get_VirtualCache_class, + ResumeDataBoxReader, tag, TagOverflow, untag, tagged_eq, UNASSIGNED, + TAGBOX, TAGVIRTUAL, tagged_list_eq, AbstractVirtualInfo, TAGCONST, + NULLREF, ResumeDataDirectReader, TAGINT, REF, VirtualInfo, VStructInfo, + VArrayInfoNotClear, VStrPlainInfo, VStrConcatInfo, VStrSliceInfo, + VUniPlainInfo, VUniConcatInfo, VUniSliceInfo, capture_resumedata, + ResumeDataLoopMemo, UNASSIGNEDVIRTUAL, INT, annlowlevel, PENDINGFIELDSP, + TAG_CONST_OFFSET) +from rpython.jit.metainterp.resumecode import ( + unpack_numbering, create_numbering) +from rpython.jit.metainterp.opencoder import Trace from rpython.jit.metainterp.optimizeopt import info -from rpython.jit.metainterp.history import ConstInt, Const, AbstractDescr -from rpython.jit.metainterp.history import ConstPtr, ConstFloat,\ - IntFrontendOp, RefFrontendOp +from rpython.jit.metainterp.history import ( + ConstInt, Const, AbstractDescr, ConstPtr, ConstFloat, IntFrontendOp, + RefFrontendOp, CONST_NULL) from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin from rpython.jit.metainterp import executor from rpython.jit.codewriter import heaptracker, longlong from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib.debug import debug_start, debug_stop, debug_print,\ - have_debug_prints + have_debug_prints from rpython.jit.metainterp.test.strategies import intconsts -from rpython.jit.metainterp import resumecode from hypothesis import given, strategies @@ -57,7 +56,7 @@ def getptrinfo(self, op, create=True): op = self.get_box_replacement(op) - return op.get_forwarded() + return op.get_forwarded() # ____________________________________________________________ @@ -185,7 +184,7 @@ def newframe(self, jitcode): frame = FakeFrame(jitcode, -1) self.framestack.append(frame) - return frame + return frame def execute_and_record(self, opnum, descr, *argboxes): resvalue = executor.execute(self.cpu, None, opnum, descr, *argboxes) @@ -228,17 +227,17 @@ gcrefnull = lltype.nullptr(llmemory.GCREF.TO) class MyCPU: - class ts: - NULLREF = gcrefnull - CONST_NULL = ConstPtr(gcrefnull) def __init__(self, values): self.values = values + def get_int_value(self, deadframe, index): assert deadframe == "deadframe" return self.values[index] + def get_ref_value(self, deadframe, index): assert deadframe == "deadframe" return self.values[index] + def get_float_value(self, deadframe, index): assert deadframe == "deadframe" return self.values[index] @@ -378,7 +377,7 @@ class FakeResumeDataReader(AbstractResumeDataReader): VirtualCache = get_VirtualCache_class('Fake') - + def allocate_with_vtable(self, descr): return FakeBuiltObject(vtable=descr) def allocate_struct(self, typedescr): @@ -521,7 +520,7 @@ def setup_resume_at_op(self, pc, exception_target, env): self.__init__(self.jitcode, pc, exception_target, *env) - + def __eq__(self, other): return self.__dict__ == other.__dict__ def __ne__(self, other): @@ -544,7 +543,7 @@ def test_rebuild_from_resumedata(): py.test.skip("XXX rewrite") b1, b2, b3 = [BoxInt(), InputArgRef(), BoxInt()] - c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] + c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] storage = Storage() fs = [FakeFrame("code0", 0, b1, c1, b2), FakeFrame("code1", 3, b3, c2, b1), @@ -568,7 +567,7 @@ def test_rebuild_from_resumedata_with_virtualizable(): py.test.skip("XXX rewrite") b1, b2, b3, b4 = [BoxInt(), InputArgRef(), BoxInt(), InputArgRef()] - c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] + c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] storage = Storage() fs = [FakeFrame("code0", 0, b1, c1, b2), FakeFrame("code1", 3, b3, c2, b1), @@ -593,7 +592,7 @@ def test_rebuild_from_resumedata_two_guards(): py.test.skip("XXX rewrite") b1, b2, b3, b4 = [BoxInt(), InputArgRef(), BoxInt(), BoxInt()] - c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] + c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)] storage = Storage() fs = [FakeFrame("code0", 0, b1, c1, b2), FakeFrame("code1", 3, b3, c2, b1), @@ -602,7 +601,7 @@ storage2 = Storage() fs = fs[:-1] + [FakeFrame("code2", 10, c3, b2, b4)] capture_resumedata(fs, None, [], storage2) - + memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage, memo) liveboxes = modifier.finish() @@ -653,7 +652,7 @@ def test_rebuild_from_resumedata_two_guards_w_virtuals(): py.test.skip("XXX rewrite") - + b1, b2, b3, b4, b5 = [BoxInt(), InputArgRef(), BoxInt(), BoxInt(), BoxInt()] c1, c2, c3, c4 = [ConstInt(1), ConstInt(2), ConstInt(3), LLtypeMixin.nodebox.constbox()] @@ -665,7 +664,7 @@ storage2 = Storage() fs = fs[:-1] + [FakeFrame("code2", 10, c3, b2, b4)] capture_resumedata(fs, None, [], storage2) - + memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo) @@ -676,12 +675,12 @@ b6 = InputArgRef() v6 = virtual_value(b6, c2, None) - v6.setfield(LLtypeMixin.nextdescr, v6) + v6.setfield(LLtypeMixin.nextdescr, v6) values = {b2: virtual_value(b2, b4, v6), b6: v6} memo.clear_box_virtual_numbers() modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage2, memo) liveboxes2 = modifier.finish() - assert len(storage2.rd_virtuals) == 2 + assert len(storage2.rd_virtuals) == 2 assert storage2.rd_virtuals[0].fieldnums == [tag(len(liveboxes2)-1, TAGBOX), tag(-1, TAGVIRTUAL)] assert storage2.rd_virtuals[1].fieldnums == [tag(2, TAGINT), @@ -712,7 +711,7 @@ fs2 = [FakeFrame("code0", 0, b1t, c1, b2t), FakeFrame("code1", 3, b3t, c2, b1t), FakeFrame("code2", 10, c3, b2t, b4t)] - assert metainterp.framestack == fs2 + assert metainterp.framestack == fs2 def test_rebuild_from_resumedata_two_guards_w_shared_virtuals(): py.test.skip("XXX rewrite") @@ -722,7 +721,7 @@ storage = Storage() fs = [FakeFrame("code0", 0, c1, b2, b3)] capture_resumedata(fs, None, [], storage) - + memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo) @@ -740,7 +739,7 @@ assert len(storage2.rd_virtuals) == 2 assert storage2.rd_virtuals[1].fieldnums == storage.rd_virtuals[0].fieldnums assert storage2.rd_virtuals[1] is storage.rd_virtuals[0] - + def test_resumedata_top_recursive_virtuals(): py.test.skip("XXX rewrite") @@ -748,7 +747,7 @@ storage = Storage() fs = [FakeFrame("code0", 0, b1, b2)] capture_resumedata(fs, None, [], storage) - + memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) v1 = virtual_value(b1, b3, None) v2 = virtual_value(b2, b3, v1) @@ -761,7 +760,7 @@ assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX), tag(1, TAGVIRTUAL)] assert storage.rd_virtuals[1].fieldnums == [tag(-1, TAGBOX), - tag(0, TAGVIRTUAL)] + tag(0, TAGVIRTUAL)] # ____________________________________________________________ @@ -787,24 +786,23 @@ demo55o = lltype.cast_opaque_ptr(llmemory.GCREF, demo55) demo66 = lltype.malloc(LLtypeMixin.NODE) demo66o = lltype.cast_opaque_ptr(llmemory.GCREF, demo66) - + def test_ResumeDataLoopMemo_refs(): - cpu = LLtypeMixin.cpu memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) - const = cpu.ts.ConstRef(demo55o) + const = ConstPtr(demo55o) tagged = memo.getconst(const) index, tagbits = untag(tagged) assert tagbits == TAGCONST - assert memo.consts[index - TAG_CONST_OFFSET] is const - tagged = memo.getconst(cpu.ts.ConstRef(demo55o)) + assert memo.consts[index - TAG_CONST_OFFSET] is const + tagged = memo.getconst(ConstPtr(demo55o)) index2, tagbits = untag(tagged) assert tagbits == TAGCONST assert index2 == index - tagged = memo.getconst(cpu.ts.ConstRef(demo66o)) + tagged = memo.getconst(ConstPtr(demo66o)) index3, tagbits = untag(tagged) assert tagbits == TAGCONST - assert index3 != index - tagged = memo.getconst(cpu.ts.CONST_NULL) + assert index3 != index + tagged = memo.getconst(CONST_NULL) assert tagged == NULLREF def test_ResumeDataLoopMemo_other(): @@ -828,7 +826,7 @@ def test_ResumeDataLoopMemo_number(): b1, b2, b3, b4, b5 = [IntFrontendOp(0), IntFrontendOp(1), IntFrontendOp(2), RefFrontendOp(3), RefFrontendOp(4)] - c1, c2, c3, c4 = [ConstInt(1), ConstInt(2), ConstInt(3), ConstInt(4)] + c1, c2, c3, c4 = [ConstInt(1), ConstInt(2), ConstInt(3), ConstInt(4)] env = [b1, c1, b2, b1, c2] metainterp_sd = FakeMetaInterpStaticData() @@ -892,7 +890,7 @@ numb_state3 = memo.number(FakeOptimizer(), 2, iter) numb3 = numb_state3.create_numbering() assert numb_state3.num_virtuals == 0 - + assert numb_state3.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)} assert unpack_numbering(numb3) == ([17, 0, 0, 2, tag(3, TAGINT), tag(4, TAGINT), tag(0, TAGBOX), tag(3, TAGINT)] + @@ -908,7 +906,7 @@ numb_state4 = memo.number(FakeOptimizer(), 3, iter) numb4 = numb_state4.create_numbering() assert numb_state4.num_virtuals == 1 - + assert numb_state4.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), b4: tag(0, TAGVIRTUAL)} assert unpack_numbering(numb4) == [17, 0, 0, 2, tag(3, TAGINT), tag(0, TAGVIRTUAL), @@ -964,7 +962,7 @@ assert memo.consts[v].getint() == item.getint() elif tag == TAGINT: assert v == item.getint() - + def test_ResumeDataLoopMemo_number_boxes(): memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) b1, b2 = [IntFrontendOp(0), IntFrontendOp(0)] @@ -1064,7 +1062,7 @@ b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**16), ConstInt(-65)] storage, t = make_storage(b1s, b2s, b3s) metainterp_sd = FakeMetaInterpStaticData() - memo = ResumeDataLoopMemo(metainterp_sd) + memo = ResumeDataLoopMemo(metainterp_sd) i = t.get_iter() modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, memo) liveboxes = modifier.finish() @@ -1095,7 +1093,7 @@ modifier2 = ResumeDataVirtualAdder(FakeOptimizer(i), storage2, storage2, i, memo) modifier2.finish() - assert len(memo.consts) == 3 + assert len(memo.consts) == 3 assert storage2.rd_consts is memo.consts @@ -1177,7 +1175,7 @@ assert_same(lst, [ConstInt(2), ConstInt(3)]) lst = reader.consume_boxes() assert_same(lst, [b1t, ConstInt(1), b1t, b1t]) - assert metainterp.trace == [] + assert metainterp.trace == [] def test_virtual_adder_make_constant(): @@ -1185,7 +1183,7 @@ b1s, b2s, b3s = [InputArgInt(1), InputArgRef(), InputArgInt(3)] b1s = ConstInt(111) storage = make_storage(b1s, b2s, b3s) - memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) + memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo) liveboxes = modifier.finish() b2t, b3t = [InputArgRef(demo55o), InputArgInt(33)] @@ -1204,7 +1202,7 @@ def test_virtual_adder_make_virtual(): b2s, b3s, b4s, b5s = [IntFrontendOp(0), IntFrontendOp(0), RefFrontendOp(0), - RefFrontendOp(0)] + RefFrontendOp(0)] c1s = ConstInt(111) storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) @@ -1542,7 +1540,7 @@ def test_invalidation_needed(): class options: failargs_limit = 10 - + metainterp_sd = FakeMetaInterpStaticData() metainterp_sd.options = options memo = ResumeDataLoopMemo(metainterp_sd) @@ -1556,5 +1554,5 @@ assert not modifier._invalidation_needed(10, 2) assert not modifier._invalidation_needed(10, 3) - assert modifier._invalidation_needed(10, 4) - + assert modifier._invalidation_needed(10, 4) + diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -33,14 +33,7 @@ nullptr = staticmethod(lltype.nullptr) cast_instance_to_base_ref = staticmethod(cast_instance_to_base_ptr) BASETYPE = llmemory.GCREF - ConstRef = history.ConstPtr loops_done_with_this_frame_ref = None # patched by compile.py - NULLREF = history.ConstPtr.value - CONST_NULL = history.ConstPtr(NULLREF) - - def new_ConstRef(self, x): - ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) - return history.ConstPtr(ptrval) def get_typeptr(self, obj): return obj.typeptr From pypy.commits at gmail.com Mon Apr 1 11:50:05 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 08:50:05 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Remove functionptr, nullptr, BASETYPE from llhelper Message-ID: <5ca2332d.1c69fb81.d6036.e654@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96395:5cde9f06eb6a Date: 2019-04-01 04:39 +0100 http://bitbucket.org/pypy/pypy/changeset/5cde9f06eb6a/ Log: Remove functionptr, nullptr, BASETYPE from llhelper diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -1622,7 +1622,7 @@ elif kind == 'i': raise jitexc.DoneWithThisFrameInt(self.get_tmpreg_i()) elif kind == 'r': - raise jitexc.DoneWithThisFrameRef(self.cpu, self.get_tmpreg_r()) + raise jitexc.DoneWithThisFrameRef(self.get_tmpreg_r()) elif kind == 'f': raise jitexc.DoneWithThisFrameFloat(self.get_tmpreg_f()) else: @@ -1631,7 +1631,7 @@ def _exit_frame_with_exception(self, e): sd = self.builder.metainterp_sd e = lltype.cast_opaque_ptr(llmemory.GCREF, e) - raise jitexc.ExitFrameWithExceptionRef(self.cpu, e) + raise jitexc.ExitFrameWithExceptionRef(e) def _handle_jitexception_in_portal(self, e): # This case is really rare, but can occur if diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -654,6 +654,7 @@ class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr): def get_result(self, cpu, deadframe): return cpu.get_int_value(deadframe, 0) + def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert jitdriver_sd.result_type == history.INT cpu = metainterp_sd.cpu @@ -662,14 +663,16 @@ class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr): def get_result(self, cpu, deadframe): return cpu.get_ref_value(deadframe, 0) + def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert jitdriver_sd.result_type == history.REF cpu = metainterp_sd.cpu - raise jitexc.DoneWithThisFrameRef(cpu, self.get_result(cpu, deadframe)) + raise jitexc.DoneWithThisFrameRef(self.get_result(cpu, deadframe)) class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr): def get_result(self, cpu, deadframe): return cpu.get_float_value(deadframe, 0) + def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert jitdriver_sd.result_type == history.FLOAT cpu = metainterp_sd.cpu @@ -679,7 +682,7 @@ def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): cpu = metainterp_sd.cpu value = cpu.get_ref_value(deadframe, 0) - raise jitexc.ExitFrameWithExceptionRef(cpu, value) + raise jitexc.ExitFrameWithExceptionRef(value) def make_and_attach_done_descrs(targets): @@ -1120,7 +1123,7 @@ if not exception: exception = cast_instance_to_gcref(memory_error) assert exception, "PropagateExceptionDescr: no exception??" - raise jitexc.ExitFrameWithExceptionRef(cpu, exception) + raise jitexc.ExitFrameWithExceptionRef(exception) def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): diff --git a/rpython/jit/metainterp/jitexc.py b/rpython/jit/metainterp/jitexc.py --- a/rpython/jit/metainterp/jitexc.py +++ b/rpython/jit/metainterp/jitexc.py @@ -1,6 +1,6 @@ from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance -from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.rtyper.llinterp import LLException from rpython.rlib.objectmodel import we_are_translated @@ -22,13 +22,15 @@ def __init__(self, result): assert lltype.typeOf(result) is lltype.Signed self.result = result + def __str__(self): return 'DoneWithThisFrameInt(%s)' % (self.result,) class DoneWithThisFrameRef(JitException): - def __init__(self, cpu, result): - assert lltype.typeOf(result) == cpu.ts.BASETYPE + def __init__(self, result): + assert lltype.typeOf(result) == llmemory.GCREF self.result = result + def __str__(self): return 'DoneWithThisFrameRef(%s)' % (self.result,) @@ -36,13 +38,15 @@ def __init__(self, result): assert lltype.typeOf(result) is longlong.FLOATSTORAGE self.result = result + def __str__(self): return 'DoneWithThisFrameFloat(%s)' % (self.result,) class ExitFrameWithExceptionRef(JitException): - def __init__(self, cpu, value): - assert lltype.typeOf(value) == cpu.ts.BASETYPE + def __init__(self, value): + assert lltype.typeOf(value) == llmemory.GCREF self.value = value + def __str__(self): return 'ExitFrameWithExceptionRef(%s)' % (self.value,) diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2131,7 +2131,7 @@ elif result_type == history.INT: raise jitexc.DoneWithThisFrameInt(int(resultbox.getint())) elif result_type == history.REF: - raise jitexc.DoneWithThisFrameRef(self.cpu, resultbox.getref_base()) + raise jitexc.DoneWithThisFrameRef(resultbox.getref_base()) elif result_type == history.FLOAT: raise jitexc.DoneWithThisFrameFloat(resultbox.getfloatstorage()) else: @@ -2165,7 +2165,8 @@ self.compile_exit_frame_with_exception(self.last_exc_box) except SwitchToBlackhole as stb: self.aborted_tracing(stb.reason) - raise jitexc.ExitFrameWithExceptionRef(self.cpu, lltype.cast_opaque_ptr(llmemory.GCREF, excvalue)) + raise jitexc.ExitFrameWithExceptionRef( + lltype.cast_opaque_ptr(llmemory.GCREF, excvalue)) def check_recursion_invariant(self): portal_call_depth = -1 @@ -2632,16 +2633,24 @@ num_green_args = self.jitdriver_sd.num_green_args num_red_args = self.jitdriver_sd.num_red_args for box in live_arg_boxes[num_green_args:num_green_args+num_red_args]: - if box.type == history.INT: args.append(box.getint()) - elif box.type == history.REF: args.append(box.getref_base()) - elif box.type == history.FLOAT: args.append(box.getfloatstorage()) - else: assert 0 + if box.type == history.INT: + args.append(box.getint()) + elif box.type == history.REF: + args.append(box.getref_base()) + elif box.type == history.FLOAT: + args.append(box.getfloatstorage()) + else: + assert 0 res = self.jitdriver_sd.warmstate.execute_assembler(loop_token, *args) kind = history.getkind(lltype.typeOf(res)) - if kind == 'void': raise jitexc.DoneWithThisFrameVoid() - if kind == 'int': raise jitexc.DoneWithThisFrameInt(res) - if kind == 'ref': raise jitexc.DoneWithThisFrameRef(self.cpu, res) - if kind == 'float': raise jitexc.DoneWithThisFrameFloat(res) + if kind == 'void': + raise jitexc.DoneWithThisFrameVoid() + if kind == 'int': + raise jitexc.DoneWithThisFrameInt(res) + if kind == 'ref': + raise jitexc.DoneWithThisFrameRef(res) + if kind == 'float': + raise jitexc.DoneWithThisFrameFloat(res) raise AssertionError(kind) def prepare_resume_from_failure(self, deadframe, inputargs, resumedescr): diff --git a/rpython/jit/metainterp/test/test_warmspot.py b/rpython/jit/metainterp/test/test_warmspot.py --- a/rpython/jit/metainterp/test/test_warmspot.py +++ b/rpython/jit/metainterp/test/test_warmspot.py @@ -601,7 +601,6 @@ exc = lltype.malloc(OBJECT) exc.typeptr = exc_vtable raise jitexc.ExitFrameWithExceptionRef( - metainterp_sd.cpu, lltype.cast_opaque_ptr(llmemory.GCREF, exc)) assert 0 diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -29,10 +29,7 @@ class LLTypeHelper(TypeSystemHelper): name = 'lltype' - functionptr = staticmethod(lltype.functionptr) - nullptr = staticmethod(lltype.nullptr) cast_instance_to_base_ref = staticmethod(cast_instance_to_base_ptr) - BASETYPE = llmemory.GCREF loops_done_with_this_frame_ref = None # patched by compile.py def get_typeptr(self, obj): diff --git a/rpython/jit/metainterp/warmspot.py b/rpython/jit/metainterp/warmspot.py --- a/rpython/jit/metainterp/warmspot.py +++ b/rpython/jit/metainterp/warmspot.py @@ -909,8 +909,8 @@ # from rpython.jit.metainterp.warmstate import specialize_value from rpython.jit.metainterp.warmstate import unspecialize_value - portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal', - graph=portalgraph) + portal_ptr = lltype.functionptr( + PORTALFUNC, 'portal', graph=portalgraph) jd._portal_ptr = portal_ptr # portalfunc_ARGS = [] From pypy.commits at gmail.com Mon Apr 1 11:50:07 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 08:50:07 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: kill cast_instance_to_base_ref, cast_to_ref and simplify some code Message-ID: <5ca2332f.1c69fb81.eb1a4.e79b@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96396:d35167b4bf4e Date: 2019-04-01 05:58 +0100 http://bitbucket.org/pypy/pypy/changeset/d35167b4bf4e/ Log: kill cast_instance_to_base_ref, cast_to_ref and simplify some code diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -1,6 +1,7 @@ import weakref from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.annlowlevel import cast_instance_to_gcref +from rpython.rtyper.annlowlevel import ( + cast_instance_to_gcref, cast_gcref_to_instance) from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.debug import debug_start, debug_stop, debug_print, have_debug_prints from rpython.rlib.rarithmetic import r_uint, intmask @@ -931,15 +932,12 @@ def __init__(self, cache): self.cache = cache - def hide(self, cpu): - ptr = cpu.ts.cast_instance_to_base_ref(self) - return cpu.ts.cast_to_ref(ptr) + def hide(self): + return cast_instance_to_gcref(self) @staticmethod - def show(cpu, gcref): - from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance - ptr = cpu.ts.cast_to_baseclass(gcref) - return cast_base_ptr_to_instance(AllVirtuals, ptr) + def show(gcref): + return cast_gcref_to_instance(AllVirtuals, gcref) def invent_fail_descr_for_op(opnum, optimizer, copied_from_descr=None): if opnum == rop.GUARD_NOT_FORCED or opnum == rop.GUARD_NOT_FORCED_2: @@ -974,7 +972,7 @@ # handle_async_forcing() just a moment ago. from rpython.jit.metainterp.blackhole import resume_in_blackhole hidden_all_virtuals = metainterp_sd.cpu.get_savedata_ref(deadframe) - obj = AllVirtuals.show(metainterp_sd.cpu, hidden_all_virtuals) + obj = AllVirtuals.show(hidden_all_virtuals) all_virtuals = obj.cache if all_virtuals is None: all_virtuals = ResumeDataDirectReader.VirtualCache([], []) @@ -1017,8 +1015,7 @@ # Handle all_virtuals: keep them for later blackholing from the # future failure of the GUARD_NOT_FORCED obj = AllVirtuals(all_virtuals) - hidden_all_virtuals = obj.hide(metainterp_sd.cpu) - metainterp_sd.cpu.set_savedata_ref(deadframe, hidden_all_virtuals) + metainterp_sd.cpu.set_savedata_ref(deadframe, obj.hide()) class ResumeFromInterpDescr(ResumeDescr): def __init__(self, original_greenkey): 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 @@ -1,6 +1,8 @@ import sys from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.annlowlevel import ( + cast_gcref_to_instance, cast_instance_to_gcref) from rpython.rlib.objectmodel import we_are_translated, Symbolic from rpython.rlib.objectmodel import compute_unique_id, specialize from rpython.rlib.rarithmetic import r_int64, is_valid_int @@ -97,14 +99,11 @@ return '%r' % (self,) def hide(self, cpu): - descr_ptr = cpu.ts.cast_instance_to_base_ref(self) - return cpu.ts.cast_to_ref(descr_ptr) + return cast_instance_to_gcref(self) @staticmethod def show(cpu, descr_gcref): - from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance - descr_ptr = cpu.ts.cast_to_baseclass(descr_gcref) - return cast_base_ptr_to_instance(AbstractDescr, descr_ptr) + return cast_gcref_to_instance(AbstractDescr, descr_gcref) def get_vinfo(self): raise NotImplementedError diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py --- a/rpython/jit/metainterp/quasiimmut.py +++ b/rpython/jit/metainterp/quasiimmut.py @@ -1,8 +1,9 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass -from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance -from rpython.jit.metainterp.history import AbstractDescr, ConstPtr, ConstInt,\ - ConstFloat +from rpython.rtyper.annlowlevel import ( + cast_base_ptr_to_instance, cast_gcref_to_instance, cast_instance_to_gcref) +from rpython.jit.metainterp.history import ( + AbstractDescr, ConstPtr, ConstInt, ConstFloat) from rpython.rlib.objectmodel import we_are_translated @@ -18,7 +19,7 @@ """ qmut_gcref = cpu.bh_getfield_gc_r(gcref, mutatefielddescr) if qmut_gcref: - qmut = QuasiImmut.show(cpu, qmut_gcref) + qmut = QuasiImmut.show(qmut_gcref) else: qmut = QuasiImmut(cpu) cpu.bh_setfield_gc_r(gcref, qmut.hide(), mutatefielddescr) @@ -43,8 +44,7 @@ qmut_ref = cpu.bh_getfield_gc_r(p, mutatefielddescr) if qmut_ref: cpu.bh_setfield_gc_r(p, ConstPtr.value, mutatefielddescr) - qmut_ptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, qmut_ref) - qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr) + qmut = cast_gcref_to_instance(QuasiImmut, qmut_ref) qmut.invalidate() @@ -60,13 +60,11 @@ self.looptokens_wrefs = [] def hide(self): - qmut_ptr = self.cpu.ts.cast_instance_to_base_ref(self) - return self.cpu.ts.cast_to_ref(qmut_ptr) + return cast_instance_to_gcref(self) @staticmethod - def show(cpu, qmut_gcref): - qmut_ptr = cpu.ts.cast_to_baseclass(qmut_gcref) - return cast_base_ptr_to_instance(QuasiImmut, qmut_ptr) + def show(qmut_gcref): + return cast_gcref_to_instance(QuasiImmut, qmut_gcref) def register_loop_token(self, wref_looptoken): if len(self.looptokens_wrefs) > self.compress_limit: diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -1,7 +1,6 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, llstr -from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.jit.metainterp import history from rpython.jit.codewriter import heaptracker from rpython.rlib.objectmodel import r_dict, specialize @@ -29,8 +28,6 @@ class LLTypeHelper(TypeSystemHelper): name = 'lltype' - cast_instance_to_base_ref = staticmethod(cast_instance_to_base_ptr) - loops_done_with_this_frame_ref = None # patched by compile.py def get_typeptr(self, obj): return obj.typeptr @@ -54,8 +51,7 @@ return llmemory.cast_ptr_to_adr(fnptr) def cls_of_box(self, box): - PTR = lltype.Ptr(rclass.OBJECT) - obj = lltype.cast_opaque_ptr(PTR, box.getref_base()) + obj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, box.getref_base()) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(heaptracker.adr2int(cls)) @@ -70,11 +66,11 @@ def get_exception_obj(self, evaluebox): # only works when translated - obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) + obj = evaluebox.getref(rclass.OBJECTPTR) return cast_base_ptr_to_instance(Exception, obj) def cast_to_baseclass(self, value): - return lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), value) + return lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) @specialize.ll() def getlength(self, array): @@ -97,8 +93,10 @@ # the value type. Note that NULL is not allowed as a key. def new_ref_dict(self): return r_dict(rd_eq, rd_hash, simple_hash_eq=True) + def new_ref_dict_2(self): return r_dict(rd_eq, rd_hash, simple_hash_eq=True) + def new_ref_dict_3(self): return r_dict(rd_eq, rd_hash, simple_hash_eq=True) @@ -110,10 +108,6 @@ return lltype.cast_opaque_ptr(TYPE, value) cast_from_ref._annspecialcase_ = 'specialize:arg(1)' - def cast_to_ref(self, value): - return lltype.cast_opaque_ptr(llmemory.GCREF, value) - cast_to_ref._annspecialcase_ = 'specialize:ll' - def getaddr_for_box(self, box): return box.getaddr() From pypy.commits at gmail.com Mon Apr 1 11:50:09 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 08:50:09 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: More cleanup Message-ID: <5ca23331.1c69fb81.b3644.a31b@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96397:4ee751fdcc36 Date: 2019-04-01 16:49 +0100 http://bitbucket.org/pypy/pypy/changeset/4ee751fdcc36/ Log: More cleanup diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -29,14 +29,6 @@ name = 'lltype' - def get_typeptr(self, obj): - return obj.typeptr - - def get_FuncType(self, ARGS, RESULT): - FUNCTYPE = lltype.FuncType(ARGS, RESULT) - FUNCPTRTYPE = lltype.Ptr(FUNCTYPE) - return FUNCTYPE, FUNCPTRTYPE - def get_superclass(self, TYPE): SUPER = TYPE.TO._first_struct()[1] if SUPER is None: @@ -69,9 +61,6 @@ obj = evaluebox.getref(rclass.OBJECTPTR) return cast_base_ptr_to_instance(Exception, obj) - def cast_to_baseclass(self, value): - return lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) - @specialize.ll() def getlength(self, array): return len(array) diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py --- a/rpython/jit/metainterp/virtualizable.py +++ b/rpython/jit/metainterp/virtualizable.py @@ -293,15 +293,14 @@ # all_graphs = self.warmrunnerdesc.translator.graphs ts = self.warmrunnerdesc.cpu.ts - (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) + FUNC = lltype.FuncType([self.VTYPEPTR], lltype.Void) funcptr = self.warmrunnerdesc.helper_func( - FUNCPTR, force_virtualizable_if_necessary) + lltype.Ptr(FUNC), force_virtualizable_if_necessary) rvirtualizable.replace_force_virtualizable_with_call( all_graphs, self.VTYPEPTR, funcptr) - (_, FUNCPTR) = ts.get_FuncType([llmemory.GCREF], lltype.Void) + FUNC = lltype.FuncType([llmemory.GCREF], lltype.Void) self.clear_vable_ptr = self.warmrunnerdesc.helper_func( - FUNCPTR, self.clear_vable_token) - FUNC = FUNCPTR.TO + lltype.Ptr(FUNC), self.clear_vable_token) ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_CANNOT_RAISE, can_invalidate=False, oopspecindex=EffectInfo.OS_JIT_FORCE_VIRTUALIZABLE) diff --git a/rpython/jit/metainterp/warmspot.py b/rpython/jit/metainterp/warmspot.py --- a/rpython/jit/metainterp/warmspot.py +++ b/rpython/jit/metainterp/warmspot.py @@ -3,10 +3,10 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import (llhelper, MixLevelHelperAnnotator, - cast_base_ptr_to_instance, hlstr, cast_instance_to_gcref) + hlstr, cast_instance_to_gcref, cast_gcref_to_instance) from rpython.rtyper.llannotation import lltype_to_annotation +from rpython.rtyper.rclass import OBJECTPTR from rpython.annotator import model as annmodel -from rpython.annotator.dictdef import DictDef from rpython.rtyper.llinterp import LLException from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache from rpython.flowspace.model import SpaceOperation, Variable, Constant @@ -665,10 +665,10 @@ jd.num_green_args = len(jd._green_args_spec) jd.num_red_args = len(jd.red_args_types) RESTYPE = graph.getreturnvar().concretetype - (jd._JIT_ENTER_FUNCTYPE, - jd._PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) - (jd._PORTAL_FUNCTYPE, - jd._PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) + jd._JIT_ENTER_FUNCTYPE = lltype.FuncType(ALLARGS, lltype.Void) + jd._PTR_JIT_ENTER_FUNCTYPE = lltype.Ptr(jd._JIT_ENTER_FUNCTYPE) + jd._PORTAL_FUNCTYPE = lltype.FuncType(ALLARGS, RESTYPE) + jd._PTR_PORTAL_FUNCTYPE = lltype.Ptr(jd._PORTAL_FUNCTYPE) # if jd.result_type == 'v': ASMRESTYPE = lltype.Void @@ -680,8 +680,8 @@ ASMRESTYPE = lltype.Float else: assert False - (_, jd._PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType( - [llmemory.GCREF, llmemory.GCREF], ASMRESTYPE) + jd._PTR_ASSEMBLER_HELPER_FUNCTYPE = lltype.Ptr(lltype.FuncType( + [llmemory.GCREF, llmemory.GCREF], ASMRESTYPE)) def rewrite_jitcell_accesses(self): jitdrivers_by_name = {} @@ -932,7 +932,6 @@ RESULT = PORTALFUNC.RESULT result_kind = history.getkind(RESULT) assert result_kind.startswith(jd.result_type) - ts = self.cpu.ts state = jd.warmstate maybe_compile_and_run = jd._maybe_compile_and_run_fn EnterJitAssembler = jd._EnterJitAssembler @@ -995,11 +994,11 @@ return e.result # if isinstance(e, jitexc.ExitFrameWithExceptionRef): - value = ts.cast_to_baseclass(e.value) if not we_are_translated(): - raise LLException(ts.get_typeptr(value), value) + value = lltype.cast_opaque_ptr(OBJECTPTR, e.value) + raise LLException(value.typeptr, value) else: - value = cast_base_ptr_to_instance(Exception, value) + value = cast_gcref_to_instance(Exception, e.value) assert value is not None raise value # @@ -1087,10 +1086,10 @@ closures = {} graphs = self.translator.graphs - _, PTR_SET_PARAM_FUNCTYPE = self.cpu.ts.get_FuncType([lltype.Signed], - lltype.Void) - _, PTR_SET_PARAM_STR_FUNCTYPE = self.cpu.ts.get_FuncType( - [lltype.Ptr(STR)], lltype.Void) + SET_PARAM_FUNC = lltype.Ptr(lltype.FuncType( + [lltype.Signed], lltype.Void)) + SET_PARAM_STR_FUNC = lltype.Ptr(lltype.FuncType( + [lltype.Ptr(STR)], lltype.Void)) def make_closure(jd, fullfuncname, is_string): if jd is None: def closure(i): @@ -1105,9 +1104,9 @@ i = hlstr(i) getattr(state, fullfuncname)(i) if is_string: - TP = PTR_SET_PARAM_STR_FUNCTYPE + TP = SET_PARAM_STR_FUNC else: - TP = PTR_SET_PARAM_FUNCTYPE + TP = SET_PARAM_FUNC funcptr = self.helper_func(TP, closure) return Constant(funcptr, TP) # From pypy.commits at gmail.com Mon Apr 1 16:58:50 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 01 Apr 2019 13:58:50 -0700 (PDT) Subject: [pypy-commit] pypy default: document arm32 build technique (njs) and link in missing rstrategies doc Message-ID: <5ca27b8a.1c69fb81.a111c.e6ef@mx.google.com> Author: Matti Picus Branch: Changeset: r96399:f62db80c3e76 Date: 2019-04-01 23:57 +0300 http://bitbucket.org/pypy/pypy/changeset/f62db80c3e76/ Log: document arm32 build technique (njs) and link in missing rstrategies doc diff --git a/rpython/doc/arm.rst b/rpython/doc/arm.rst --- a/rpython/doc/arm.rst +++ b/rpython/doc/arm.rst @@ -3,6 +3,13 @@ Cross-translating for ARM ========================= +.. note:: + + The information here is unfortunately only of historical value. Scratchbox is + no longer functional. However it seems translation of ARM32 is possible on a + aarch64 machine using chroot and ``setarch linux32 pypy rpython/bin/rpython + ...`` + Here we describe the setup required and the steps needed to follow to translate an interpreter using the RPython translator to target ARM using a cross compilation toolchain. diff --git a/rpython/doc/index.rst b/rpython/doc/index.rst --- a/rpython/doc/index.rst +++ b/rpython/doc/index.rst @@ -48,6 +48,7 @@ rlib rffi examples + rstrategies RPython internals From pypy.commits at gmail.com Mon Apr 1 23:41:08 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 20:41:08 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: remove more stuff from rpython.jit.metainterp.typesystem Message-ID: <5ca2d9d4.1c69fb81.793c7.33e0@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96402:8ffa1a681639 Date: 2019-04-02 03:32 +0100 http://bitbucket.org/pypy/pypy/changeset/8ffa1a681639/ Log: remove more stuff from rpython.jit.metainterp.typesystem diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -1,14 +1,15 @@ -import py, sys, random, os, struct, operator, math -from rpython.jit.metainterp.history import (AbstractFailDescr, - AbstractDescr, - BasicFailDescr, - BasicFinalDescr, - JitCellToken, TargetToken, - ConstInt, ConstPtr, - ConstFloat, Const) -from rpython.jit.metainterp.resoperation import ResOperation, rop, InputArgInt,\ - InputArgFloat, opname, InputArgRef -from rpython.jit.metainterp.typesystem import deref +import py +import sys +import random +import os +import struct +import operator +import math +from rpython.jit.metainterp.history import ( + AbstractFailDescr, AbstractDescr, BasicFailDescr, BasicFinalDescr, + JitCellToken, TargetToken, ConstInt, ConstPtr, ConstFloat, Const) +from rpython.jit.metainterp.resoperation import ( + ResOperation, rop, InputArgInt, InputArgFloat, InputArgRef) from rpython.jit.metainterp.executor import wrap_constant from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse @@ -55,7 +56,7 @@ add_loop_instructions = ['overload for a specific cpu'] bridge_loop_instructions = ['overload for a specific cpu'] - + def execute_operation(self, opname, valueboxes, result_type, descr=None): inputargs, operations = self._get_single_operation_list(opname, result_type, @@ -506,7 +507,7 @@ return chr(ord(c) + 1) FPTR = self.Ptr(self.FuncType([lltype.Char], lltype.Char)) func_ptr = llhelper(FPTR, func) - calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char, + calldescr = cpu.calldescrof(FPTR.TO, (lltype.Char,), lltype.Char, EffectInfo.MOST_GENERAL) x = cpu.bh_call_i(self.get_funcbox(cpu, func_ptr).value, [ord('A')], None, None, calldescr) @@ -519,7 +520,7 @@ FPTR = self.Ptr(self.FuncType([lltype.Float, lltype.Signed], lltype.Float)) func_ptr = llhelper(FPTR, func) - FTP = deref(FPTR) + FTP = FPTR.TO calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT, EffectInfo.MOST_GENERAL) x = cpu.bh_call_f(self.get_funcbox(cpu, func_ptr).value, @@ -548,7 +549,7 @@ # FPTR = self.Ptr(self.FuncType([TP, TP], TP)) func_ptr = llhelper(FPTR, func) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcbox = self.get_funcbox(cpu, func_ptr) # first, try it with the "normal" calldescr calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -630,7 +631,7 @@ TP = lltype.Signed FPTR = self.Ptr(self.FuncType([TP, TP], TP)) func_ptr = llhelper(FPTR, f) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcconst = self.get_funcbox(self.cpu, func_ptr) funcbox = InputArgInt(funcconst.getint()) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -656,7 +657,7 @@ # FPTR = self.Ptr(self.FuncType([TP] * nb_args, TP)) func_ptr = llhelper(FPTR, func_ints) - FUNC = deref(FPTR) + FUNC = FPTR.TO calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) @@ -1820,7 +1821,7 @@ EffectInfo.OS_MATH_READ_TIMESTAMP) FPTR = self.Ptr(self.FuncType([], lltype.SignedLongLong)) func_ptr = llhelper(FPTR, rtimer.read_timestamp) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcbox = self.get_funcbox(self.cpu, func_ptr) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo) @@ -4454,7 +4455,7 @@ effectinfo = EffectInfo([], [], [], [], [], [], EffectInfo.EF_CANNOT_RAISE, EffectInfo.OS_MATH_SQRT) FPTR = self.Ptr(self.FuncType([lltype.Float], lltype.Float)) func_ptr = llhelper(FPTR, math_sqrt) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcbox = self.get_funcbox(self.cpu, func_ptr) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo) @@ -4641,12 +4642,12 @@ assert a + 12 == g assert a + 14 == h assert a + 16 == i - FPTR = self.Ptr(self.FuncType([lltype.Signed]*9, lltype.Void)) + FPTR = self.Ptr(self.FuncType([lltype.Signed] * 9, lltype.Void)) func_ptr = llhelper(FPTR, func) cpu = self.cpu - calldescr = cpu.calldescrof(deref(FPTR), (lltype.Signed,)*9, lltype.Void, + calldescr = cpu.calldescrof(FPTR.TO, (lltype.Signed,) * 9, lltype.Void, EffectInfo.MOST_GENERAL) - faildescr=BasicFailDescr(42) + faildescr = BasicFailDescr(42) loop = parse(""" [i0] label(i0, descr=targettoken1) diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py --- a/rpython/jit/codewriter/effectinfo.py +++ b/rpython/jit/codewriter/effectinfo.py @@ -1,5 +1,4 @@ import sys -from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem from rpython.rtyper.rclass import OBJECT from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.translator.backendopt.graphanalyze import BoolGraphAnalyzer @@ -298,19 +297,19 @@ write_descrs_interiorfields = [] def add_struct(descrs_fields, (_, T, fieldname)): - T = deref(T) + T = T.TO if consider_struct(T, fieldname): descr = cpu.fielddescrof(T, fieldname) descrs_fields.append(descr) def add_array(descrs_arrays, (_, T)): - ARRAY = deref(T) + ARRAY = T.TO if consider_array(ARRAY): descr = cpu.arraydescrof(ARRAY) descrs_arrays.append(descr) def add_interiorfield(descrs_interiorfields, (_, T, fieldname)): - T = deref(T) + T = T.TO if not isinstance(T, lltype.Array): return # let's not consider structs for now if not consider_array(T): @@ -329,7 +328,7 @@ extraef = list() for tup in effects: if tup[0] == "interiorfield" or tup[0] == "readinteriorfield": - T = deref(tup[1]) + T = tup[1].TO if isinstance(T, lltype.Array) and consider_array(T): val = (tup[0].replace("interiorfield", "array"), tup[1]) @@ -377,7 +376,7 @@ can_collect) def consider_struct(TYPE, fieldname): - if fieldType(TYPE, fieldname) is lltype.Void: + if getattr(TYPE, fieldname) is lltype.Void: return False if not isinstance(TYPE, lltype.GcStruct): # can be a non-GC-struct return False @@ -389,7 +388,7 @@ return True def consider_array(ARRAY): - if arrayItem(ARRAY) is lltype.Void: + if ARRAY.OF is lltype.Void: return False if not isinstance(ARRAY, lltype.GcArray): # can be a non-GC-array return False diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -6,10 +6,8 @@ from rpython.jit.codewriter.policy import log from rpython.jit.metainterp import quasiimmut from rpython.jit.metainterp.history import getkind -from rpython.jit.metainterp.typesystem import deref, arrayItem from rpython.jit.metainterp.blackhole import BlackholeInterpreter -from rpython.flowspace.model import SpaceOperation, Variable, Constant,\ - c_last_exception +from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.rlib import objectmodel from rpython.rlib.jit import _we_are_jitted from rpython.rlib.rgc import lltype_is_gc @@ -1729,9 +1727,9 @@ (in which case the original call is written as a residual call). """ if oopspec_name.startswith('new'): - LIST = deref(op.result.concretetype) + LIST = op.result.concretetype.TO else: - LIST = deref(args[0].concretetype) + LIST = args[0].concretetype.TO resizable = isinstance(LIST, lltype.GcStruct) assert resizable == (not isinstance(LIST, lltype.GcArray)) if resizable: diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py --- a/rpython/jit/codewriter/support.py +++ b/rpython/jit/codewriter/support.py @@ -4,7 +4,6 @@ from rpython.rtyper.llannotation import lltype_to_annotation from rpython.annotator.policy import AnnotatorPolicy from rpython.flowspace.model import Variable, Constant -from rpython.jit.metainterp.typesystem import deref from rpython.rlib import rgc from rpython.rlib.jit import elidable, oopspec from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask @@ -142,7 +141,7 @@ assert len(lst) == len(args_v), ( "not supported so far: 'greens' variables contain Void") # a crash here means that you have to reorder the variable named in - # the JitDriver. + # the JitDriver. lst2 = sort_vars(lst) assert lst == lst2, ("You have to reorder the variables named in " "the JitDriver (both the 'greens' and 'reds' independently). " @@ -786,7 +785,7 @@ bk = rtyper.annotator.bookkeeper ll_restype = ll_res if impl.need_result_type != 'exact': - ll_restype = deref(ll_restype) + ll_restype = ll_restype.TO desc = bk.getdesc(ll_restype) else: class TestingDesc(object): diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1352,7 +1352,9 @@ last_exc_value = metainterp.last_exc_value assert last_exc_value assert metainterp.class_of_last_exc_is_const - if not metainterp.cpu.ts.instanceOf(ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, last_exc_value)), vtablebox): + if not metainterp.cpu.ts.instanceOf( + ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, last_exc_value)), + vtablebox): self.pc = next_exc_target @arguments("box", "orgpc") @@ -1824,7 +1826,7 @@ to handle an indirect_call that may need to be inlined.""" if isinstance(funcbox, Const): sd = self.metainterp.staticdata - key = sd.cpu.ts.getaddr_for_box(funcbox) + key = funcbox.getaddr() jitcode = sd.bytecode_for_address(key) if jitcode is not None: # we should follow calls to this graph diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -1,24 +1,9 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass -from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, llstr from rpython.jit.metainterp import history from rpython.jit.codewriter import heaptracker -from rpython.rlib.objectmodel import r_dict, specialize +from rpython.rlib.objectmodel import r_dict -def deref(T): - assert isinstance(T, lltype.Ptr) - return T.TO - - -def fieldType(T, name): - assert isinstance(T, lltype.Struct) - return getattr(T, name) - -def arrayItem(ARRAY): - try: - return ARRAY.OF - except AttributeError: - return ARRAY.ITEM class TypeSystemHelper(object): @@ -40,14 +25,6 @@ real_instance = instbox.getref(rclass.OBJECTPTR) return rclass.ll_isinstance(real_instance, bounding_class) - def get_exception_box(self, etype): - return history.ConstInt(etype) - - def get_exception_obj(self, evaluebox): - # only works when translated - obj = evaluebox.getref(rclass.OBJECTPTR) - return cast_base_ptr_to_instance(Exception, obj) - # A dict whose keys are refs (like the .value of BoxPtr). # It is an r_dict on lltype. Two copies, to avoid conflicts with # the value type. Note that NULL is not allowed as a key. @@ -60,13 +37,6 @@ def new_ref_dict_3(self): return r_dict(rd_eq, rd_hash, simple_hash_eq=True) - def cast_vtable_to_hashable(self, cpu, ptr): - adr = llmemory.cast_ptr_to_adr(ptr) - return heaptracker.adr2int(adr) - - def getaddr_for_box(self, box): - return box.getaddr() - def rd_eq(ref1, ref2): return ref1 == ref2 diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py --- a/rpython/jit/metainterp/virtualizable.py +++ b/rpython/jit/metainterp/virtualizable.py @@ -1,6 +1,5 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp import history -from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem from rpython.jit.metainterp.warmstate import wrap, unwrap from rpython.rlib.unroll import unrolling_iterable from rpython.rtyper import rvirtualizable @@ -42,12 +41,12 @@ self.static_fields = static_fields self.array_fields = array_fields # - FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields] + FIELDTYPES = [getattr(VTYPE, name) for name in static_fields] ARRAYITEMTYPES = [] for name in array_fields: - ARRAYPTR = fieldType(VTYPE, name) - ARRAY = deref(ARRAYPTR) + ARRAYPTR = getattr(VTYPE, name) assert isinstance(ARRAYPTR, lltype.Ptr) + ARRAY = ARRAYPTR.TO if not isinstance(ARRAY, lltype.GcArray): raise Exception( "The virtualizable field '%s' is not an array (found %r)." @@ -55,8 +54,8 @@ " the list is not resized at run-time. You can do that by" " using rpython.rlib.debug.make_sure_not_resized()." % (name, ARRAY)) - ARRAYITEMTYPES.append(arrayItem(ARRAY)) - self.array_descrs = [cpu.arraydescrof(deref(fieldType(VTYPE, name))) + ARRAYITEMTYPES.append(ARRAY.OF) + self.array_descrs = [cpu.arraydescrof(getattr(VTYPE, name).TO) for name in array_fields] # self.num_static_extra_boxes = len(static_fields) diff --git a/rpython/rtyper/test/test_rclass.py b/rpython/rtyper/test/test_rclass.py --- a/rpython/rtyper/test/test_rclass.py +++ b/rpython/rtyper/test/test_rclass.py @@ -747,7 +747,6 @@ assert summary(graph) == {} def test_immutable_fields(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_fields_ = ["x", "y[*]"] @@ -758,13 +757,12 @@ def f(): return A(3, []) t, typer, graph = self.gengraph(f, []) - A_TYPE = deref(graph.getreturnvar().concretetype) + A_TYPE = graph.getreturnvar().concretetype.TO accessor = A_TYPE._hints["immutable_fields"] assert accessor.fields == {"inst_x": IR_IMMUTABLE, "inst_y": IR_IMMUTABLE_ARRAY} def test_immutable_fields_subclass_1(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_fields_ = ["x"] def __init__(self, x): @@ -777,12 +775,11 @@ def f(): return B(3, 5) t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO accessor = B_TYPE._hints["immutable_fields"] assert accessor.fields == {"inst_x": IR_IMMUTABLE} def test_immutable_fields_subclass_2(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_fields_ = ["x"] def __init__(self, x): @@ -796,13 +793,12 @@ def f(): return B(3, 5) t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO accessor = B_TYPE._hints["immutable_fields"] assert accessor.fields == {"inst_x": IR_IMMUTABLE, "inst_y": IR_IMMUTABLE} def test_immutable_fields_only_in_subclass(self): - from rpython.jit.metainterp.typesystem import deref class A(object): def __init__(self, x): self.x = x @@ -815,7 +811,7 @@ def f(): return B(3, 5) t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO accessor = B_TYPE._hints["immutable_fields"] assert accessor.fields == {"inst_y": IR_IMMUTABLE} @@ -844,7 +840,6 @@ py.test.raises(ImmutableConflictError, self.gengraph, f, []) def test_immutable_ok_inheritance_2(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_fields_ = ['v'] class B(A): @@ -854,7 +849,7 @@ B().w = 456 return B() t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO assert B_TYPE._hints["immutable"] A_TYPE = B_TYPE.super accessor = A_TYPE._hints["immutable_fields"] @@ -862,7 +857,6 @@ def test_immutable_subclass_1(self): from rpython.rtyper.rclass import ImmutableConflictError - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_ = True class B(A): @@ -874,7 +868,6 @@ py.test.raises(ImmutableConflictError, self.gengraph, f, []) def test_immutable_subclass_2(self): - from rpython.jit.metainterp.typesystem import deref class A(object): pass class B(A): @@ -884,11 +877,10 @@ B().v = 123 return B() t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO assert B_TYPE._hints["immutable"] def test_immutable_subclass_void(self): - from rpython.jit.metainterp.typesystem import deref class A(object): pass class B(A): @@ -900,11 +892,10 @@ B().v = 123 # even though only B is declared _immutable_ return B() t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO assert B_TYPE._hints["immutable"] def test_quasi_immutable(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_fields_ = ['x', 'y', 'a?', 'b?'] class B(A): @@ -920,7 +911,7 @@ b.b = 45 return B() t, typer, graph = self.gengraph(f, []) - B_TYPE = deref(graph.getreturnvar().concretetype) + B_TYPE = graph.getreturnvar().concretetype.TO accessor = B_TYPE._hints["immutable_fields"] assert accessor.fields == {"inst_y": IR_IMMUTABLE, "inst_b": IR_QUASIIMMUTABLE} @@ -931,7 +922,6 @@ assert found == ['mutate_a', 'mutate_a', 'mutate_b'] def test_quasi_immutable_clashes_with_immutable(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_ = True _immutable_fields_ = ['a?'] @@ -944,7 +934,6 @@ self.gengraph(f, []) def test_quasi_immutable_array(self): - from rpython.jit.metainterp.typesystem import deref class A(object): _immutable_fields_ = ['c?[*]'] class B(A): @@ -954,7 +943,7 @@ a.c = [3, 4, 5] return A() t, typer, graph = self.gengraph(f, []) - A_TYPE = deref(graph.getreturnvar().concretetype) + A_TYPE = graph.getreturnvar().concretetype.TO accessor = A_TYPE._hints["immutable_fields"] assert accessor.fields == {"inst_c": IR_QUASIIMMUTABLE_ARRAY} found = [] From pypy.commits at gmail.com Mon Apr 1 23:41:11 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 01 Apr 2019 20:41:11 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Inline instanceOf() into its only caller and simplify Message-ID: <5ca2d9d7.1c69fb81.5df77.790b@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96403:49a109ff63cc Date: 2019-04-02 04:40 +0100 http://bitbucket.org/pypy/pypy/changeset/49a109ff63cc/ Log: Inline instanceOf() into its only caller and simplify diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1352,9 +1352,9 @@ last_exc_value = metainterp.last_exc_value assert last_exc_value assert metainterp.class_of_last_exc_is_const - if not metainterp.cpu.ts.instanceOf( - ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, last_exc_value)), - vtablebox): + cls = llmemory.cast_adr_to_ptr(vtablebox.getaddr(), rclass.CLASSTYPE) + real_instance = rclass.ll_cast_to_object(last_exc_value) + if not rclass.ll_isinstance(real_instance, cls): self.pc = next_exc_target @arguments("box", "orgpc") diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -19,12 +19,6 @@ cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(heaptracker.adr2int(cls)) - def instanceOf(self, instbox, clsbox): - adr = clsbox.getaddr() - bounding_class = llmemory.cast_adr_to_ptr(adr, rclass.CLASSTYPE) - real_instance = instbox.getref(rclass.OBJECTPTR) - return rclass.ll_isinstance(real_instance, bounding_class) - # A dict whose keys are refs (like the .value of BoxPtr). # It is an r_dict on lltype. Two copies, to avoid conflicts with # the value type. Note that NULL is not allowed as a key. From pypy.commits at gmail.com Tue Apr 2 02:24:46 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Apr 2019 23:24:46 -0700 (PDT) Subject: [pypy-commit] pypy.org extradoc: remove donation button temporarily Message-ID: <5ca3002e.1c69fb81.eec73.7b44@mx.google.com> Author: Armin Rigo Branch: extradoc Changeset: r945:9dacd393c375 Date: 2019-04-02 08:24 +0200 http://bitbucket.org/pypy/pypy.org/changeset/9dacd393c375/ Log: remove donation button temporarily diff --git a/don2.html b/don2.html --- a/don2.html +++ b/don2.html @@ -6,16 +6,21 @@
  • + +
  • +
  • diff --git a/source/contact.txt b/source/contact.txt --- a/source/contact.txt +++ b/source/contact.txt @@ -10,7 +10,7 @@ * mailing list: `pypy-dev at python.org`__ -* for security related issues, non-public funding enquiries etc. please contact pypy at sfconservancy.org +* for security related issues, non-public funding enquiries etc. please contact pypy-z at python.org * the bitbucket `bug tracker`_ (registration required to open new issues or to comment) From pypy.commits at gmail.com Tue Apr 2 09:55:18 2019 From: pypy.commits at gmail.com (rlamy) Date: Tue, 02 Apr 2019 06:55:18 -0700 (PDT) Subject: [pypy-commit] cffi default: Fix deprecated uses of pytest.raises() Message-ID: <5ca369c6.1c69fb81.48e18.2ed4@mx.google.com> Author: Ronan Lamy Branch: Changeset: r3252:326ee02b5d12 Date: 2019-03-12 16:28 +0000 http://bitbucket.org/cffi/cffi/changeset/326ee02b5d12/ Log: Fix deprecated uses of pytest.raises() diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1,4 +1,6 @@ import py +import pytest + def _setup_path(): import os, sys if '__pypy__' in sys.builtin_module_names: @@ -315,8 +317,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -444,7 +448,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -537,13 +542,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -558,10 +566,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -609,10 +621,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -625,8 +641,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -777,10 +795,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -792,30 +812,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1636,7 +1667,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1766,14 +1798,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1782,7 +1817,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1842,14 +1878,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2181,8 +2220,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): + s.a1 = b'a' + with pytest.raises(TypeError): + s.a1 = bytechr(0xFF) s.a1 = u+'\u1234' assert s.a1 == u+'\u1234' if pyuni4: @@ -2196,7 +2237,8 @@ s.a1 = u+'\ud807\udf44' assert s.a1 == u+'\U00011f44' else: - py.test.raises(TypeError, "s.a1 = u+'\U00012345'") + with pytest.raises(TypeError): + s.a1 = u+'\U00012345' # BWCharArray = new_array_type(BWCharP, None) a = newp(BWCharArray, u+'hello \u1234 world') @@ -2220,7 +2262,8 @@ assert list(a) == expected got = [a[i] for i in range(4)] assert got == expected - py.test.raises(IndexError, 'a[4]') + with pytest.raises(IndexError): + a[4] # w = cast(BWChar, 'a') assert repr(w) == "" % (typename, mandatory_u_prefix) @@ -2352,9 +2395,11 @@ def test_cannot_dereference_void(): BVoidP = new_pointer_type(new_void_type()) p = cast(BVoidP, 123456) - py.test.raises(TypeError, "p[0]") + with pytest.raises(TypeError): + p[0] p = cast(BVoidP, 0) - py.test.raises((TypeError, RuntimeError), "p[0]") + with pytest.raises((TypeError, RuntimeError)): + p[0] def test_iter(): BInt = new_primitive_type("int") @@ -2377,12 +2422,12 @@ assert (q == p) is False assert (q != p) is True if strict_compare: - py.test.raises(TypeError, "p < q") - py.test.raises(TypeError, "p <= q") - py.test.raises(TypeError, "q < p") - py.test.raises(TypeError, "q <= p") - py.test.raises(TypeError, "p > q") - py.test.raises(TypeError, "p >= q") + with pytest.raises(TypeError): p < q + with pytest.raises(TypeError): p <= q + with pytest.raises(TypeError): q < p + with pytest.raises(TypeError): q <= p + with pytest.raises(TypeError): p > q + with pytest.raises(TypeError): p >= q r = cast(BVoidP, p) assert (p < r) is False assert (p <= r) is True @@ -2428,7 +2473,8 @@ try: expected = b"hi there\x00"[i] except IndexError: - py.test.raises(IndexError, "buf[i]") + with pytest.raises(IndexError): + buf[i] else: assert buf[i] == bitem2bchr(expected) # --mb_slice-- @@ -2455,15 +2501,18 @@ try: expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + with pytest.raises(IndexError): + buf[i] = bytechr(i & 0xff) else: buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) - py.test.raises(ValueError, 'buf[:] = b"shorter"') - py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + with pytest.raises(ValueError): + buf[:] = b"shorter" + with pytest.raises(ValueError): + buf[:] = b"this is much too long!" buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" buf[:2] = b"HI" @@ -2537,14 +2586,16 @@ BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) x = newp(BCharP) - py.test.raises(TypeError, "del x[0]") + with pytest.raises(TypeError): + del x[0] def test_bug_delattr(): BLong = new_primitive_type("long") BStruct = new_struct_type("struct foo") complete_struct_or_union(BStruct, [('a1', BLong, -1)]) x = newp(new_pointer_type(BStruct)) - py.test.raises(AttributeError, "del x.a1") + with pytest.raises(AttributeError): + del x.a1 def test_variable_length_struct(): py.test.skip("later") @@ -2562,7 +2613,8 @@ assert sizeof(x) == 6 * size_of_long() x[4] = 123 assert x[4] == 123 - py.test.raises(IndexError, "x[5]") + with pytest.raises(IndexError): + x[5] assert len(x.a2) == 5 # py.test.raises(TypeError, newp, BStructP, [123]) @@ -2814,7 +2866,8 @@ BCharP = new_pointer_type(new_primitive_type("char")) p = newp(BCharP, b'X') q = cast(BBoolP, p) - py.test.raises(ValueError, "q[0]") + with pytest.raises(ValueError): + q[0] py.test.raises(TypeError, newp, BBoolP, b'\x00') assert newp(BBoolP, 0)[0] is False assert newp(BBoolP, 1)[0] is True @@ -3114,8 +3167,10 @@ assert c[1] == 123 assert c[3] == 456 assert d[2] == 456 - py.test.raises(IndexError, "d[3]") - py.test.raises(IndexError, "d[-1]") + with pytest.raises(IndexError): + d[3] + with pytest.raises(IndexError): + d[-1] def test_slice_ptr(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -3133,7 +3188,8 @@ c = newp(BIntArray, 5) c[0:5] assert len(c[5:5]) == 0 - py.test.raises(IndexError, "c[-1:1]") + with pytest.raises(IndexError): + c[-1:1] cp = c + 0 cp[-1:1] @@ -3141,17 +3197,23 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) - e = py.test.raises(IndexError, "c[:5]") + with pytest.raises(IndexError) as e: + c[:5] assert str(e.value) == "slice start must be specified" - e = py.test.raises(IndexError, "c[4:]") + with pytest.raises(IndexError) as e: + c[4:] assert str(e.value) == "slice stop must be specified" - e = py.test.raises(IndexError, "c[1:2:3]") + with pytest.raises(IndexError) as e: + c[1:2:3] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[1:2:1]") + with pytest.raises(IndexError) as e: + c[1:2:1] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[4:2]") + with pytest.raises(IndexError) as e: + c[4:2] assert str(e.value) == "slice start > stop" - e = py.test.raises(IndexError, "c[6:6]") + with pytest.raises(IndexError) as e: + c[6:6] assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): @@ -3165,9 +3227,11 @@ assert list(c) == [0, 100, 300, 400, 0] cp[-1:1] = iter([500, 600]) assert list(c) == [0, 100, 500, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = [1000]") + with pytest.raises(ValueError): + cp[-1:1] = [1000] assert list(c) == [0, 100, 1000, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + with pytest.raises(ValueError): + cp[-1:1] = (700, 800, 900) assert list(c) == [0, 100, 700, 800, 0] def test_setslice_array(): @@ -3427,10 +3491,14 @@ assert sizeof(q[0]) == sizeof(BStruct) # # error cases - py.test.raises(IndexError, "p.y[4]") - py.test.raises(TypeError, "p.y = cast(BIntP, 0)") - py.test.raises(TypeError, "p.y = 15") - py.test.raises(TypeError, "p.y = None") + with pytest.raises(IndexError): + p.y[4] + with pytest.raises(TypeError): + p.y = cast(BIntP, 0) + with pytest.raises(TypeError): + p.y = 15 + with pytest.raises(TypeError): + p.y = None # # accepting this may be specified by the C99 standard, # or a GCC strangeness... @@ -3535,8 +3603,10 @@ p[2:5] = [b"*", b"Z", b"T"] p[1:3] = b"XY" assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"] - py.test.raises(TypeError, "p[1:5] = u+'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = u+'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] # for typename in ["wchar_t", "char16_t", "char32_t"]: BUniChar = new_primitive_type(typename) @@ -3545,8 +3615,10 @@ p[2:5] = [u+"*", u+"Z", u+"T"] p[1:3] = u+"XY" assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"] - py.test.raises(TypeError, "p[1:5] = b'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = b'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] def test_void_p_arithmetic(): BVoid = new_void_type() @@ -3557,10 +3629,14 @@ assert int(cast(BInt, p - (-42))) == 100042 assert (p + 42) - p == 42 q = cast(new_pointer_type(new_primitive_type("char")), 100000) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)") - py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + p + cast(new_primitive_type('int'), 42) + with pytest.raises(TypeError): + p - cast(new_primitive_type('int'), 42) def test_sizeof_sliced_array(): BInt = new_primitive_type("int") @@ -3775,8 +3851,10 @@ assert p1[0] == lst[0] assert p1[1] == lst[1] assert p1[2] == lst[2] - py.test.raises(IndexError, "p1[3]") - py.test.raises(IndexError, "p1[-1]") + with pytest.raises(IndexError): + p1[3] + with pytest.raises(IndexError): + p1[-1] # py.test.raises(TypeError, from_buffer, BInt, bytestring) py.test.raises(TypeError, from_buffer, BIntP, bytestring) @@ -3787,8 +3865,10 @@ assert len(p2) == 2 assert p2[0] == lst[0] assert p2[1] == lst[1] - py.test.raises(IndexError, "p2[2]") - py.test.raises(IndexError, "p2[-1]") + with pytest.raises(IndexError): + p2[2] + with pytest.raises(IndexError): + p2[-1] assert p2 == p1 # BIntA4 = new_array_type(BIntP, 4) # int[4]: too big @@ -3804,7 +3884,8 @@ assert typeof(p1) is BStructA assert p1[0].a1 == lst[0] assert p1[0].a2 == lst[1] - py.test.raises(IndexError, "p1[1]") + with pytest.raises(IndexError): + p1[1] # BEmptyStruct = new_struct_type("empty") complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) @@ -3896,10 +3977,14 @@ BInt = new_primitive_type("int") BIntPtr = new_pointer_type(BInt) p = cast(BIntPtr, 0) - py.test.raises(RuntimeError, "p[0]") - py.test.raises(RuntimeError, "p[0] = 42") - py.test.raises(RuntimeError, "p[42]") - py.test.raises(RuntimeError, "p[42] = -1") + with pytest.raises(RuntimeError): + p[0] + with pytest.raises(RuntimeError): + p[0] = 42 + with pytest.raises(RuntimeError): + p[42] + with pytest.raises(RuntimeError): + p[42] = -1 def test_mixup(): BStruct1 = new_struct_type("foo") @@ -3915,10 +4000,12 @@ pp2 = newp(BStruct2PtrPtr) pp3 = newp(BStruct3PtrPtr) pp1[0] = pp1[0] - e = py.test.raises(TypeError, "pp3[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp3[0] = pp1[0] assert str(e.value).startswith("initializer for ctype 'bar *' must be a ") assert str(e.value).endswith(", not cdata 'foo *'") - e = py.test.raises(TypeError, "pp2[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp2[0] = pp1[0] assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to " "be 'foo *', but the types are different (check " "that you are not e.g. mixing up different ffi " @@ -4107,14 +4194,14 @@ assert (a != b) is True assert (b != a) is True if strict_compare: - py.test.raises(TypeError, "a < b") - py.test.raises(TypeError, "a <= b") - py.test.raises(TypeError, "a > b") - py.test.raises(TypeError, "a >= b") - py.test.raises(TypeError, "b < a") - py.test.raises(TypeError, "b <= a") - py.test.raises(TypeError, "b > a") - py.test.raises(TypeError, "b >= a") + with pytest.raises(TypeError): a < b + with pytest.raises(TypeError): a <= b + with pytest.raises(TypeError): a > b + with pytest.raises(TypeError): a >= b + with pytest.raises(TypeError): b < a + with pytest.raises(TypeError): b <= a + with pytest.raises(TypeError): b > a + with pytest.raises(TypeError): b >= a elif a < b: assert_lt(a, b) else: @@ -4160,7 +4247,8 @@ BIntP = new_pointer_type(new_primitive_type("int")) p = newp(BIntP) p[0] = 42 - py.test.raises(IndexError, "p[1]") + with pytest.raises(IndexError): + p[1] release(p) # here, reading p[0] might give garbage or segfault... release(p) # no effect @@ -4196,8 +4284,12 @@ def test_explicit_release_badtype_contextmgr(): BIntP = new_pointer_type(new_primitive_type("int")) p = cast(BIntP, 12345) - py.test.raises(ValueError, "with p: pass") - py.test.raises(ValueError, "with p: pass") + with pytest.raises(ValueError): + with p: + pass + with pytest.raises(ValueError): + with p: + pass def test_explicit_release_gc(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -4257,7 +4349,8 @@ BCharA = new_array_type(BCharP, None) a += b't' * 10 p = from_buffer(BCharA, a) - py.test.raises(BufferError, "a += b'u' * 100") + with pytest.raises(BufferError): + a += b'u' * 100 release(p) a += b'v' * 100 release(p) # no effect diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py --- a/testing/cffi0/backend_tests.py +++ b/testing/cffi0/backend_tests.py @@ -1,4 +1,5 @@ import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -112,10 +113,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -140,18 +145,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -259,7 +267,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -386,7 +395,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -422,13 +432,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -450,8 +462,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -511,11 +525,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -591,7 +607,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -615,7 +632,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -633,7 +651,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -657,18 +676,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -687,7 +709,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -912,10 +935,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -950,11 +977,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1011,17 +1041,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1279,7 +1315,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/testing/cffi0/test_ffi_backend.py b/testing/cffi0/test_ffi_backend.py --- a/testing/cffi0/test_ffi_backend.py +++ b/testing/cffi0/test_ffi_backend.py @@ -298,12 +298,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/testing/cffi0/test_function.py b/testing/cffi0/test_function.py --- a/testing/cffi0/test_function.py +++ b/testing/cffi0/test_function.py @@ -1,4 +1,5 @@ import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -90,7 +91,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -1,4 +1,5 @@ import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from testing.support import * @@ -589,7 +590,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -647,7 +649,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1463,8 +1466,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1532,7 +1537,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) diff --git a/testing/cffi1/test_ffi_obj.py b/testing/cffi1/test_ffi_obj.py --- a/testing/cffi1/test_ffi_obj.py +++ b/testing/cffi1/test_ffi_obj.py @@ -1,4 +1,5 @@ import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -85,9 +86,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py --- a/testing/cffi1/test_new_ffi_1.py +++ b/testing/cffi1/test_new_ffi_1.py @@ -1,4 +1,5 @@ import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -186,10 +187,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -212,18 +217,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -324,7 +332,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -445,7 +454,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -478,13 +488,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -502,8 +514,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -555,11 +569,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with py.test.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -625,7 +641,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -648,7 +665,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -664,7 +682,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -685,17 +704,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -713,7 +735,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -922,10 +945,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -947,11 +974,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1000,17 +1030,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1235,7 +1271,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1752,7 +1789,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == 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 @@ -1,5 +1,6 @@ import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from testing.udir import udir @@ -188,20 +189,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -247,7 +254,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -263,7 +271,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -315,8 +324,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -387,8 +398,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -398,8 +411,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1020,8 +1035,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1034,7 +1051,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1043,8 +1061,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1054,7 +1074,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1064,8 +1085,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1338,7 +1361,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py --- a/testing/cffi1/test_verify1.py +++ b/testing/cffi1/test_verify1.py @@ -1,4 +1,5 @@ import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -571,7 +572,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -629,7 +631,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1433,8 +1436,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1502,7 +1507,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2193,7 +2199,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") From pypy.commits at gmail.com Tue Apr 2 09:55:20 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 06:55:20 -0700 (PDT) Subject: [pypy-commit] cffi default: style Message-ID: <5ca369c8.1c69fb81.4f15.1ac4@mx.google.com> Author: Armin Rigo Branch: Changeset: r3253:b89baed6d697 Date: 2019-04-02 15:37 +0200 http://bitbucket.org/cffi/cffi/changeset/b89baed6d697/ Log: style diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py --- a/testing/cffi1/test_new_ffi_1.py +++ b/testing/cffi1/test_new_ffi_1.py @@ -574,7 +574,7 @@ # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - with py.test.raises((AttributeError, TypeError)): + with pytest.raises((AttributeError, TypeError)): del u.a assert repr(u) == "" % ( SIZE_OF_INT,) From pypy.commits at gmail.com Tue Apr 2 09:55:22 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 06:55:22 -0700 (PDT) Subject: [pypy-commit] cffi default: merge heads Message-ID: <5ca369ca.1c69fb81.a1e90.fc7b@mx.google.com> Author: Armin Rigo Branch: Changeset: r3254:1af377542a51 Date: 2019-04-02 15:42 +0200 http://bitbucket.org/cffi/cffi/changeset/1af377542a51/ Log: merge heads diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -466,3 +466,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -21,7 +21,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -2104,6 +2105,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py --- a/testing/cffi1/test_verify1.py +++ b/testing/cffi1/test_verify1.py @@ -23,7 +23,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py --- a/testing/embedding/test_basic.py +++ b/testing/embedding/test_basic.py @@ -172,7 +172,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result From pypy.commits at gmail.com Tue Apr 2 10:03:30 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:03:30 -0700 (PDT) Subject: [pypy-commit] cffi py3.8-interp-dict: hg merge default Message-ID: <5ca36bb2.1c69fb81.1b4a7.a8e8@mx.google.com> Author: Armin Rigo Branch: py3.8-interp-dict Changeset: r3255:a0845a00fa4c Date: 2019-04-02 15:55 +0200 http://bitbucket.org/cffi/cffi/changeset/a0845a00fa4c/ Log: hg merge default diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1,4 +1,6 @@ import py +import pytest + def _setup_path(): import os, sys if '__pypy__' in sys.builtin_module_names: @@ -315,8 +317,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -444,7 +448,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -537,13 +542,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -558,10 +566,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -609,10 +621,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -625,8 +641,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -777,10 +795,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -792,30 +812,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1636,7 +1667,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1766,14 +1798,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1782,7 +1817,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1842,14 +1878,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2181,8 +2220,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): + s.a1 = b'a' + with pytest.raises(TypeError): + s.a1 = bytechr(0xFF) s.a1 = u+'\u1234' assert s.a1 == u+'\u1234' if pyuni4: @@ -2196,7 +2237,8 @@ s.a1 = u+'\ud807\udf44' assert s.a1 == u+'\U00011f44' else: - py.test.raises(TypeError, "s.a1 = u+'\U00012345'") + with pytest.raises(TypeError): + s.a1 = u+'\U00012345' # BWCharArray = new_array_type(BWCharP, None) a = newp(BWCharArray, u+'hello \u1234 world') @@ -2220,7 +2262,8 @@ assert list(a) == expected got = [a[i] for i in range(4)] assert got == expected - py.test.raises(IndexError, 'a[4]') + with pytest.raises(IndexError): + a[4] # w = cast(BWChar, 'a') assert repr(w) == "" % (typename, mandatory_u_prefix) @@ -2352,9 +2395,11 @@ def test_cannot_dereference_void(): BVoidP = new_pointer_type(new_void_type()) p = cast(BVoidP, 123456) - py.test.raises(TypeError, "p[0]") + with pytest.raises(TypeError): + p[0] p = cast(BVoidP, 0) - py.test.raises((TypeError, RuntimeError), "p[0]") + with pytest.raises((TypeError, RuntimeError)): + p[0] def test_iter(): BInt = new_primitive_type("int") @@ -2377,12 +2422,12 @@ assert (q == p) is False assert (q != p) is True if strict_compare: - py.test.raises(TypeError, "p < q") - py.test.raises(TypeError, "p <= q") - py.test.raises(TypeError, "q < p") - py.test.raises(TypeError, "q <= p") - py.test.raises(TypeError, "p > q") - py.test.raises(TypeError, "p >= q") + with pytest.raises(TypeError): p < q + with pytest.raises(TypeError): p <= q + with pytest.raises(TypeError): q < p + with pytest.raises(TypeError): q <= p + with pytest.raises(TypeError): p > q + with pytest.raises(TypeError): p >= q r = cast(BVoidP, p) assert (p < r) is False assert (p <= r) is True @@ -2428,7 +2473,8 @@ try: expected = b"hi there\x00"[i] except IndexError: - py.test.raises(IndexError, "buf[i]") + with pytest.raises(IndexError): + buf[i] else: assert buf[i] == bitem2bchr(expected) # --mb_slice-- @@ -2455,15 +2501,18 @@ try: expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + with pytest.raises(IndexError): + buf[i] = bytechr(i & 0xff) else: buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) - py.test.raises(ValueError, 'buf[:] = b"shorter"') - py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + with pytest.raises(ValueError): + buf[:] = b"shorter" + with pytest.raises(ValueError): + buf[:] = b"this is much too long!" buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" buf[:2] = b"HI" @@ -2537,14 +2586,16 @@ BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) x = newp(BCharP) - py.test.raises(TypeError, "del x[0]") + with pytest.raises(TypeError): + del x[0] def test_bug_delattr(): BLong = new_primitive_type("long") BStruct = new_struct_type("struct foo") complete_struct_or_union(BStruct, [('a1', BLong, -1)]) x = newp(new_pointer_type(BStruct)) - py.test.raises(AttributeError, "del x.a1") + with pytest.raises(AttributeError): + del x.a1 def test_variable_length_struct(): py.test.skip("later") @@ -2562,7 +2613,8 @@ assert sizeof(x) == 6 * size_of_long() x[4] = 123 assert x[4] == 123 - py.test.raises(IndexError, "x[5]") + with pytest.raises(IndexError): + x[5] assert len(x.a2) == 5 # py.test.raises(TypeError, newp, BStructP, [123]) @@ -2814,7 +2866,8 @@ BCharP = new_pointer_type(new_primitive_type("char")) p = newp(BCharP, b'X') q = cast(BBoolP, p) - py.test.raises(ValueError, "q[0]") + with pytest.raises(ValueError): + q[0] py.test.raises(TypeError, newp, BBoolP, b'\x00') assert newp(BBoolP, 0)[0] is False assert newp(BBoolP, 1)[0] is True @@ -3114,8 +3167,10 @@ assert c[1] == 123 assert c[3] == 456 assert d[2] == 456 - py.test.raises(IndexError, "d[3]") - py.test.raises(IndexError, "d[-1]") + with pytest.raises(IndexError): + d[3] + with pytest.raises(IndexError): + d[-1] def test_slice_ptr(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -3133,7 +3188,8 @@ c = newp(BIntArray, 5) c[0:5] assert len(c[5:5]) == 0 - py.test.raises(IndexError, "c[-1:1]") + with pytest.raises(IndexError): + c[-1:1] cp = c + 0 cp[-1:1] @@ -3141,17 +3197,23 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) - e = py.test.raises(IndexError, "c[:5]") + with pytest.raises(IndexError) as e: + c[:5] assert str(e.value) == "slice start must be specified" - e = py.test.raises(IndexError, "c[4:]") + with pytest.raises(IndexError) as e: + c[4:] assert str(e.value) == "slice stop must be specified" - e = py.test.raises(IndexError, "c[1:2:3]") + with pytest.raises(IndexError) as e: + c[1:2:3] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[1:2:1]") + with pytest.raises(IndexError) as e: + c[1:2:1] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[4:2]") + with pytest.raises(IndexError) as e: + c[4:2] assert str(e.value) == "slice start > stop" - e = py.test.raises(IndexError, "c[6:6]") + with pytest.raises(IndexError) as e: + c[6:6] assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): @@ -3165,9 +3227,11 @@ assert list(c) == [0, 100, 300, 400, 0] cp[-1:1] = iter([500, 600]) assert list(c) == [0, 100, 500, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = [1000]") + with pytest.raises(ValueError): + cp[-1:1] = [1000] assert list(c) == [0, 100, 1000, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + with pytest.raises(ValueError): + cp[-1:1] = (700, 800, 900) assert list(c) == [0, 100, 700, 800, 0] def test_setslice_array(): @@ -3427,10 +3491,14 @@ assert sizeof(q[0]) == sizeof(BStruct) # # error cases - py.test.raises(IndexError, "p.y[4]") - py.test.raises(TypeError, "p.y = cast(BIntP, 0)") - py.test.raises(TypeError, "p.y = 15") - py.test.raises(TypeError, "p.y = None") + with pytest.raises(IndexError): + p.y[4] + with pytest.raises(TypeError): + p.y = cast(BIntP, 0) + with pytest.raises(TypeError): + p.y = 15 + with pytest.raises(TypeError): + p.y = None # # accepting this may be specified by the C99 standard, # or a GCC strangeness... @@ -3535,8 +3603,10 @@ p[2:5] = [b"*", b"Z", b"T"] p[1:3] = b"XY" assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"] - py.test.raises(TypeError, "p[1:5] = u+'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = u+'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] # for typename in ["wchar_t", "char16_t", "char32_t"]: BUniChar = new_primitive_type(typename) @@ -3545,8 +3615,10 @@ p[2:5] = [u+"*", u+"Z", u+"T"] p[1:3] = u+"XY" assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"] - py.test.raises(TypeError, "p[1:5] = b'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = b'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] def test_void_p_arithmetic(): BVoid = new_void_type() @@ -3557,10 +3629,14 @@ assert int(cast(BInt, p - (-42))) == 100042 assert (p + 42) - p == 42 q = cast(new_pointer_type(new_primitive_type("char")), 100000) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)") - py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + p + cast(new_primitive_type('int'), 42) + with pytest.raises(TypeError): + p - cast(new_primitive_type('int'), 42) def test_sizeof_sliced_array(): BInt = new_primitive_type("int") @@ -3775,8 +3851,10 @@ assert p1[0] == lst[0] assert p1[1] == lst[1] assert p1[2] == lst[2] - py.test.raises(IndexError, "p1[3]") - py.test.raises(IndexError, "p1[-1]") + with pytest.raises(IndexError): + p1[3] + with pytest.raises(IndexError): + p1[-1] # py.test.raises(TypeError, from_buffer, BInt, bytestring) py.test.raises(TypeError, from_buffer, BIntP, bytestring) @@ -3787,8 +3865,10 @@ assert len(p2) == 2 assert p2[0] == lst[0] assert p2[1] == lst[1] - py.test.raises(IndexError, "p2[2]") - py.test.raises(IndexError, "p2[-1]") + with pytest.raises(IndexError): + p2[2] + with pytest.raises(IndexError): + p2[-1] assert p2 == p1 # BIntA4 = new_array_type(BIntP, 4) # int[4]: too big @@ -3804,7 +3884,8 @@ assert typeof(p1) is BStructA assert p1[0].a1 == lst[0] assert p1[0].a2 == lst[1] - py.test.raises(IndexError, "p1[1]") + with pytest.raises(IndexError): + p1[1] # BEmptyStruct = new_struct_type("empty") complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) @@ -3896,10 +3977,14 @@ BInt = new_primitive_type("int") BIntPtr = new_pointer_type(BInt) p = cast(BIntPtr, 0) - py.test.raises(RuntimeError, "p[0]") - py.test.raises(RuntimeError, "p[0] = 42") - py.test.raises(RuntimeError, "p[42]") - py.test.raises(RuntimeError, "p[42] = -1") + with pytest.raises(RuntimeError): + p[0] + with pytest.raises(RuntimeError): + p[0] = 42 + with pytest.raises(RuntimeError): + p[42] + with pytest.raises(RuntimeError): + p[42] = -1 def test_mixup(): BStruct1 = new_struct_type("foo") @@ -3915,10 +4000,12 @@ pp2 = newp(BStruct2PtrPtr) pp3 = newp(BStruct3PtrPtr) pp1[0] = pp1[0] - e = py.test.raises(TypeError, "pp3[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp3[0] = pp1[0] assert str(e.value).startswith("initializer for ctype 'bar *' must be a ") assert str(e.value).endswith(", not cdata 'foo *'") - e = py.test.raises(TypeError, "pp2[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp2[0] = pp1[0] assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to " "be 'foo *', but the types are different (check " "that you are not e.g. mixing up different ffi " @@ -4107,14 +4194,14 @@ assert (a != b) is True assert (b != a) is True if strict_compare: - py.test.raises(TypeError, "a < b") - py.test.raises(TypeError, "a <= b") - py.test.raises(TypeError, "a > b") - py.test.raises(TypeError, "a >= b") - py.test.raises(TypeError, "b < a") - py.test.raises(TypeError, "b <= a") - py.test.raises(TypeError, "b > a") - py.test.raises(TypeError, "b >= a") + with pytest.raises(TypeError): a < b + with pytest.raises(TypeError): a <= b + with pytest.raises(TypeError): a > b + with pytest.raises(TypeError): a >= b + with pytest.raises(TypeError): b < a + with pytest.raises(TypeError): b <= a + with pytest.raises(TypeError): b > a + with pytest.raises(TypeError): b >= a elif a < b: assert_lt(a, b) else: @@ -4160,7 +4247,8 @@ BIntP = new_pointer_type(new_primitive_type("int")) p = newp(BIntP) p[0] = 42 - py.test.raises(IndexError, "p[1]") + with pytest.raises(IndexError): + p[1] release(p) # here, reading p[0] might give garbage or segfault... release(p) # no effect @@ -4196,8 +4284,12 @@ def test_explicit_release_badtype_contextmgr(): BIntP = new_pointer_type(new_primitive_type("int")) p = cast(BIntP, 12345) - py.test.raises(ValueError, "with p: pass") - py.test.raises(ValueError, "with p: pass") + with pytest.raises(ValueError): + with p: + pass + with pytest.raises(ValueError): + with p: + pass def test_explicit_release_gc(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -4257,7 +4349,8 @@ BCharA = new_array_type(BCharP, None) a += b't' * 10 p = from_buffer(BCharA, a) - py.test.raises(BufferError, "a += b'u' * 100") + with pytest.raises(BufferError): + a += b'u' * 100 release(p) a += b'v' * 100 release(p) # no effect diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py --- a/testing/cffi0/backend_tests.py +++ b/testing/cffi0/backend_tests.py @@ -1,4 +1,5 @@ import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -112,10 +113,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -140,18 +145,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -259,7 +267,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -386,7 +395,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -422,13 +432,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -450,8 +462,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -511,11 +525,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -591,7 +607,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -615,7 +632,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -633,7 +651,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -657,18 +676,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -687,7 +709,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -912,10 +935,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -950,11 +977,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1011,17 +1041,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1279,7 +1315,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/testing/cffi0/test_ffi_backend.py b/testing/cffi0/test_ffi_backend.py --- a/testing/cffi0/test_ffi_backend.py +++ b/testing/cffi0/test_ffi_backend.py @@ -298,12 +298,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/testing/cffi0/test_function.py b/testing/cffi0/test_function.py --- a/testing/cffi0/test_function.py +++ b/testing/cffi0/test_function.py @@ -1,4 +1,5 @@ import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -90,7 +91,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -466,3 +466,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -1,4 +1,5 @@ import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from testing.support import * @@ -590,7 +591,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +650,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1467,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1538,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2105,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/testing/cffi1/test_ffi_obj.py b/testing/cffi1/test_ffi_obj.py --- a/testing/cffi1/test_ffi_obj.py +++ b/testing/cffi1/test_ffi_obj.py @@ -1,4 +1,5 @@ import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -85,9 +86,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py --- a/testing/cffi1/test_new_ffi_1.py +++ b/testing/cffi1/test_new_ffi_1.py @@ -1,4 +1,5 @@ import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -186,10 +187,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -212,18 +217,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -324,7 +332,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -445,7 +454,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -478,13 +488,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -502,8 +514,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -555,11 +569,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -625,7 +641,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -648,7 +665,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -664,7 +682,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -685,17 +704,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -713,7 +735,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -922,10 +945,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -947,11 +974,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1000,17 +1030,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1235,7 +1271,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1752,7 +1789,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == 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 @@ -1,5 +1,6 @@ import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from testing.udir import udir @@ -188,20 +189,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -247,7 +254,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -263,7 +271,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -315,8 +324,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -387,8 +398,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -398,8 +411,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1020,8 +1035,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1034,7 +1051,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1043,8 +1061,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1054,7 +1074,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1064,8 +1085,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1338,7 +1361,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py --- a/testing/cffi1/test_verify1.py +++ b/testing/cffi1/test_verify1.py @@ -1,4 +1,5 @@ import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -572,7 +573,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +632,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1437,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1508,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2200,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") From pypy.commits at gmail.com Tue Apr 2 10:03:32 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:03:32 -0700 (PDT) Subject: [pypy-commit] cffi py3.8-interp-dict: close branch, ready for merge (python 3.8a3 was released) Message-ID: <5ca36bb4.1c69fb81.eec73.3afd@mx.google.com> Author: Armin Rigo Branch: py3.8-interp-dict Changeset: r3256:25a0189f4638 Date: 2019-04-02 16:02 +0200 http://bitbucket.org/cffi/cffi/changeset/25a0189f4638/ Log: close branch, ready for merge (python 3.8a3 was released) From pypy.commits at gmail.com Tue Apr 2 10:03:35 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:03:35 -0700 (PDT) Subject: [pypy-commit] cffi default: merge py3.8-interp-dict: use the official way to do that Message-ID: <5ca36bb7.1c69fb81.aed9d.d442@mx.google.com> Author: Armin Rigo Branch: Changeset: r3257:5aeca29219db Date: 2019-04-02 16:03 +0200 http://bitbucket.org/cffi/cffi/changeset/5aeca29219db/ Log: merge py3.8-interp-dict: use the official way to do that diff --git a/c/call_python.c b/c/call_python.c --- a/c/call_python.c +++ b/c/call_python.c @@ -1,10 +1,18 @@ #if PY_VERSION_HEX >= 0x03080000 -# define Py_BUILD_CORE -/* for access to the fields of PyInterpreterState */ -# include "internal/pycore_pystate.h" -# undef Py_BUILD_CORE +# define HAVE_PYINTERPSTATE_GETDICT #endif + +static PyObject *_current_interp_key(void) +{ + PyInterpreterState *interp = PyThreadState_GET()->interp; +#ifdef HAVE_PYINTERPSTATE_GETDICT + return PyInterpreterState_GetDict(interp); /* shared reference */ +#else + return interp->modules; +#endif +} + static PyObject *_get_interpstate_dict(void) { /* Hack around to return a dict that is subinterpreter-local. @@ -14,7 +22,7 @@ */ static PyObject *attr_name = NULL; PyThreadState *tstate; - PyObject *d, *builtins; + PyObject *d, *interpdict; int err; tstate = PyThreadState_GET(); @@ -23,8 +31,13 @@ return NULL; } - builtins = tstate->interp->builtins; - if (builtins == NULL) { + PyInterpreterState *interp = tstate->interp; +#ifdef HAVE_PYINTERPSTATE_GETDICT + interpdict = PyInterpreterState_GetDict(interp); /* shared reference */ +#else + interpdict = interp->builtins; +#endif + if (interpdict == NULL) { /* subinterpreter was cleared already, or is being cleared right now, to a point that is too much for us to continue */ return NULL; @@ -38,13 +51,13 @@ goto error; } - d = PyDict_GetItem(builtins, attr_name); + d = PyDict_GetItem(interpdict, attr_name); if (d == NULL) { d = PyDict_New(); if (d == NULL) goto error; - err = PyDict_SetItem(builtins, attr_name, d); - Py_DECREF(d); /* if successful, there is one ref left in builtins */ + err = PyDict_SetItem(interpdict, attr_name, d); + Py_DECREF(d); /* if successful, there is one ref left in interpdict */ if (err < 0) goto error; } @@ -163,7 +176,7 @@ if (infotuple == NULL) return 3; /* no ffi.def_extern() from this subinterpreter */ - new1 = PyThreadState_GET()->interp->modules; + new1 = _current_interp_key(); Py_INCREF(new1); Py_INCREF(infotuple); old1 = (PyObject *)externpy->reserved1; @@ -252,7 +265,7 @@ } else { PyGILState_STATE state = gil_ensure(); - if (externpy->reserved1 != PyThreadState_GET()->interp->modules) { + if (externpy->reserved1 != _current_interp_key()) { /* Update the (reserved1, reserved2) cache. This will fail if we didn't call @ffi.def_extern() in this particular subinterpreter. */ From pypy.commits at gmail.com Tue Apr 2 10:26:42 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:26:42 -0700 (PDT) Subject: [pypy-commit] pypy default: update to cffi/5aeca29219db Message-ID: <5ca37122.1c69fb81.7eb24.1a69@mx.google.com> Author: Armin Rigo Branch: Changeset: r96404:67af7a9e5ca2 Date: 2019-04-02 16:25 +0200 http://bitbucket.org/pypy/pypy/changeset/67af7a9e5ca2/ Log: update to cffi/5aeca29219db diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -113,10 +114,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -141,18 +146,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -260,7 +268,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -387,7 +396,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -423,13 +433,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -451,8 +463,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -512,11 +526,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -592,7 +608,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -616,7 +633,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -634,7 +652,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -658,18 +677,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -688,7 +710,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -913,10 +936,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -951,11 +978,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1012,17 +1042,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1280,7 +1316,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py --- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py +++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py @@ -130,6 +130,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -269,12 +299,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py --- a/extra_tests/cffi_tests/cffi0/test_function.py +++ b/extra_tests/cffi_tests/cffi0/test_function.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -91,7 +92,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -467,3 +467,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * @@ -21,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -590,7 +592,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +651,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1468,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1539,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2106,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py --- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py +++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -86,9 +87,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -187,10 +188,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -213,18 +218,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -325,7 +333,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -446,7 +455,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -479,13 +489,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -503,8 +515,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -556,11 +570,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -626,7 +642,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -649,7 +666,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -665,7 +683,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -686,17 +705,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -714,7 +736,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -923,10 +946,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -948,11 +975,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1001,17 +1031,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1236,7 +1272,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1753,7 +1790,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -1,6 +1,7 @@ # Generated by pypy/tool/import_cffi.py import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from extra_tests.cffi_tests.udir import udir @@ -189,20 +190,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -248,7 +255,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -264,7 +272,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -316,8 +325,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -388,8 +399,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -399,8 +412,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1021,8 +1036,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1035,7 +1052,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1044,8 +1062,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1055,7 +1075,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1065,8 +1086,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1339,7 +1362,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -23,7 +24,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error @@ -572,7 +574,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +633,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1438,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1509,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2201,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -173,7 +173,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -304,8 +304,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -433,7 +435,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -526,13 +529,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -547,10 +553,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -598,10 +608,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -614,8 +628,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -766,10 +782,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -781,30 +799,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1625,7 +1654,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1755,14 +1785,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1771,7 +1804,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1831,14 +1865,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2170,8 +2207,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): + s.a1 = b'a' + with pytest.raises(TypeError): + s.a1 = bytechr(0xFF) s.a1 = u+'\u1234' assert s.a1 == u+'\u1234' if pyuni4: @@ -2185,7 +2224,8 @@ s.a1 = u+'\ud807\udf44' assert s.a1 == u+'\U00011f44' else: - py.test.raises(TypeError, "s.a1 = u+'\U00012345'") + with pytest.raises(TypeError): + s.a1 = u+'\U00012345' # BWCharArray = new_array_type(BWCharP, None) a = newp(BWCharArray, u+'hello \u1234 world') @@ -2209,7 +2249,8 @@ assert list(a) == expected got = [a[i] for i in range(4)] assert got == expected - py.test.raises(IndexError, 'a[4]') + with pytest.raises(IndexError): + a[4] # w = cast(BWChar, 'a') assert repr(w) == "" % (typename, mandatory_u_prefix) @@ -2341,9 +2382,11 @@ def test_cannot_dereference_void(): BVoidP = new_pointer_type(new_void_type()) p = cast(BVoidP, 123456) - py.test.raises(TypeError, "p[0]") + with pytest.raises(TypeError): + p[0] p = cast(BVoidP, 0) - py.test.raises((TypeError, RuntimeError), "p[0]") + with pytest.raises((TypeError, RuntimeError)): + p[0] def test_iter(): BInt = new_primitive_type("int") @@ -2366,12 +2409,12 @@ assert (q == p) is False assert (q != p) is True if strict_compare: - py.test.raises(TypeError, "p < q") - py.test.raises(TypeError, "p <= q") - py.test.raises(TypeError, "q < p") - py.test.raises(TypeError, "q <= p") - py.test.raises(TypeError, "p > q") - py.test.raises(TypeError, "p >= q") + with pytest.raises(TypeError): p < q + with pytest.raises(TypeError): p <= q + with pytest.raises(TypeError): q < p + with pytest.raises(TypeError): q <= p + with pytest.raises(TypeError): p > q + with pytest.raises(TypeError): p >= q r = cast(BVoidP, p) assert (p < r) is False assert (p <= r) is True @@ -2417,7 +2460,8 @@ try: expected = b"hi there\x00"[i] except IndexError: - py.test.raises(IndexError, "buf[i]") + with pytest.raises(IndexError): + buf[i] else: assert buf[i] == bitem2bchr(expected) # --mb_slice-- @@ -2444,15 +2488,18 @@ try: expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + with pytest.raises(IndexError): + buf[i] = bytechr(i & 0xff) else: buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) - py.test.raises(ValueError, 'buf[:] = b"shorter"') - py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + with pytest.raises(ValueError): + buf[:] = b"shorter" + with pytest.raises(ValueError): + buf[:] = b"this is much too long!" buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" buf[:2] = b"HI" @@ -2526,14 +2573,16 @@ BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) x = newp(BCharP) - py.test.raises(TypeError, "del x[0]") + with pytest.raises(TypeError): + del x[0] def test_bug_delattr(): BLong = new_primitive_type("long") BStruct = new_struct_type("struct foo") complete_struct_or_union(BStruct, [('a1', BLong, -1)]) x = newp(new_pointer_type(BStruct)) - py.test.raises(AttributeError, "del x.a1") + with pytest.raises(AttributeError): + del x.a1 def test_variable_length_struct(): py.test.skip("later") @@ -2551,7 +2600,8 @@ assert sizeof(x) == 6 * size_of_long() x[4] = 123 assert x[4] == 123 - py.test.raises(IndexError, "x[5]") + with pytest.raises(IndexError): + x[5] assert len(x.a2) == 5 # py.test.raises(TypeError, newp, BStructP, [123]) @@ -2803,7 +2853,8 @@ BCharP = new_pointer_type(new_primitive_type("char")) p = newp(BCharP, b'X') q = cast(BBoolP, p) - py.test.raises(ValueError, "q[0]") + with pytest.raises(ValueError): + q[0] py.test.raises(TypeError, newp, BBoolP, b'\x00') assert newp(BBoolP, 0)[0] is False assert newp(BBoolP, 1)[0] is True @@ -3103,8 +3154,10 @@ assert c[1] == 123 assert c[3] == 456 assert d[2] == 456 - py.test.raises(IndexError, "d[3]") - py.test.raises(IndexError, "d[-1]") + with pytest.raises(IndexError): + d[3] + with pytest.raises(IndexError): + d[-1] def test_slice_ptr(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -3122,7 +3175,8 @@ c = newp(BIntArray, 5) c[0:5] assert len(c[5:5]) == 0 - py.test.raises(IndexError, "c[-1:1]") + with pytest.raises(IndexError): + c[-1:1] cp = c + 0 cp[-1:1] @@ -3130,17 +3184,23 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) - e = py.test.raises(IndexError, "c[:5]") + with pytest.raises(IndexError) as e: + c[:5] assert str(e.value) == "slice start must be specified" - e = py.test.raises(IndexError, "c[4:]") + with pytest.raises(IndexError) as e: + c[4:] assert str(e.value) == "slice stop must be specified" - e = py.test.raises(IndexError, "c[1:2:3]") + with pytest.raises(IndexError) as e: + c[1:2:3] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[1:2:1]") + with pytest.raises(IndexError) as e: + c[1:2:1] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[4:2]") + with pytest.raises(IndexError) as e: + c[4:2] assert str(e.value) == "slice start > stop" - e = py.test.raises(IndexError, "c[6:6]") + with pytest.raises(IndexError) as e: + c[6:6] assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): @@ -3154,9 +3214,11 @@ assert list(c) == [0, 100, 300, 400, 0] cp[-1:1] = iter([500, 600]) assert list(c) == [0, 100, 500, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = [1000]") + with pytest.raises(ValueError): + cp[-1:1] = [1000] assert list(c) == [0, 100, 1000, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + with pytest.raises(ValueError): + cp[-1:1] = (700, 800, 900) assert list(c) == [0, 100, 700, 800, 0] def test_setslice_array(): @@ -3416,10 +3478,14 @@ assert sizeof(q[0]) == sizeof(BStruct) # # error cases - py.test.raises(IndexError, "p.y[4]") - py.test.raises(TypeError, "p.y = cast(BIntP, 0)") - py.test.raises(TypeError, "p.y = 15") - py.test.raises(TypeError, "p.y = None") + with pytest.raises(IndexError): + p.y[4] + with pytest.raises(TypeError): + p.y = cast(BIntP, 0) + with pytest.raises(TypeError): + p.y = 15 + with pytest.raises(TypeError): + p.y = None # # accepting this may be specified by the C99 standard, # or a GCC strangeness... @@ -3524,8 +3590,10 @@ p[2:5] = [b"*", b"Z", b"T"] p[1:3] = b"XY" assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"] - py.test.raises(TypeError, "p[1:5] = u+'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = u+'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] # for typename in ["wchar_t", "char16_t", "char32_t"]: BUniChar = new_primitive_type(typename) @@ -3534,8 +3602,10 @@ p[2:5] = [u+"*", u+"Z", u+"T"] p[1:3] = u+"XY" assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"] - py.test.raises(TypeError, "p[1:5] = b'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = b'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] def test_void_p_arithmetic(): BVoid = new_void_type() @@ -3546,10 +3616,14 @@ assert int(cast(BInt, p - (-42))) == 100042 assert (p + 42) - p == 42 q = cast(new_pointer_type(new_primitive_type("char")), 100000) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)") - py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + p + cast(new_primitive_type('int'), 42) + with pytest.raises(TypeError): + p - cast(new_primitive_type('int'), 42) def test_sizeof_sliced_array(): BInt = new_primitive_type("int") @@ -3764,8 +3838,10 @@ assert p1[0] == lst[0] assert p1[1] == lst[1] assert p1[2] == lst[2] - py.test.raises(IndexError, "p1[3]") - py.test.raises(IndexError, "p1[-1]") + with pytest.raises(IndexError): + p1[3] + with pytest.raises(IndexError): + p1[-1] # py.test.raises(TypeError, from_buffer, BInt, bytestring) py.test.raises(TypeError, from_buffer, BIntP, bytestring) @@ -3776,8 +3852,10 @@ assert len(p2) == 2 assert p2[0] == lst[0] assert p2[1] == lst[1] - py.test.raises(IndexError, "p2[2]") - py.test.raises(IndexError, "p2[-1]") + with pytest.raises(IndexError): + p2[2] + with pytest.raises(IndexError): + p2[-1] assert p2 == p1 # BIntA4 = new_array_type(BIntP, 4) # int[4]: too big @@ -3793,7 +3871,8 @@ assert typeof(p1) is BStructA assert p1[0].a1 == lst[0] assert p1[0].a2 == lst[1] - py.test.raises(IndexError, "p1[1]") + with pytest.raises(IndexError): + p1[1] # BEmptyStruct = new_struct_type("empty") complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) @@ -3885,10 +3964,14 @@ BInt = new_primitive_type("int") BIntPtr = new_pointer_type(BInt) p = cast(BIntPtr, 0) - py.test.raises(RuntimeError, "p[0]") - py.test.raises(RuntimeError, "p[0] = 42") - py.test.raises(RuntimeError, "p[42]") - py.test.raises(RuntimeError, "p[42] = -1") + with pytest.raises(RuntimeError): + p[0] + with pytest.raises(RuntimeError): + p[0] = 42 + with pytest.raises(RuntimeError): + p[42] + with pytest.raises(RuntimeError): + p[42] = -1 def test_mixup(): BStruct1 = new_struct_type("foo") @@ -3904,10 +3987,12 @@ pp2 = newp(BStruct2PtrPtr) pp3 = newp(BStruct3PtrPtr) pp1[0] = pp1[0] - e = py.test.raises(TypeError, "pp3[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp3[0] = pp1[0] assert str(e.value).startswith("initializer for ctype 'bar *' must be a ") assert str(e.value).endswith(", not cdata 'foo *'") - e = py.test.raises(TypeError, "pp2[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp2[0] = pp1[0] assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to " "be 'foo *', but the types are different (check " "that you are not e.g. mixing up different ffi " @@ -4096,14 +4181,14 @@ assert (a != b) is True assert (b != a) is True if strict_compare: - py.test.raises(TypeError, "a < b") - py.test.raises(TypeError, "a <= b") - py.test.raises(TypeError, "a > b") - py.test.raises(TypeError, "a >= b") - py.test.raises(TypeError, "b < a") - py.test.raises(TypeError, "b <= a") - py.test.raises(TypeError, "b > a") - py.test.raises(TypeError, "b >= a") + with pytest.raises(TypeError): a < b + with pytest.raises(TypeError): a <= b + with pytest.raises(TypeError): a > b + with pytest.raises(TypeError): a >= b + with pytest.raises(TypeError): b < a + with pytest.raises(TypeError): b <= a + with pytest.raises(TypeError): b > a + with pytest.raises(TypeError): b >= a elif a < b: assert_lt(a, b) else: @@ -4149,7 +4234,8 @@ BIntP = new_pointer_type(new_primitive_type("int")) p = newp(BIntP) p[0] = 42 - py.test.raises(IndexError, "p[1]") + with pytest.raises(IndexError): + p[1] release(p) # here, reading p[0] might give garbage or segfault... release(p) # no effect @@ -4185,8 +4271,12 @@ def test_explicit_release_badtype_contextmgr(): BIntP = new_pointer_type(new_primitive_type("int")) p = cast(BIntP, 12345) - py.test.raises(ValueError, "with p: pass") - py.test.raises(ValueError, "with p: pass") + with pytest.raises(ValueError): + with p: + pass + with pytest.raises(ValueError): + with p: + pass def test_explicit_release_gc(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -4246,7 +4336,8 @@ BCharA = new_array_type(BCharP, None) a += b't' * 10 p = from_buffer(BCharA, a) - py.test.raises(BufferError, "a += b'u' * 100") + with pytest.raises(BufferError): + a += b'u' * 100 release(p) a += b'v' * 100 release(p) # no effect diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -124,6 +124,7 @@ print >> f, ' class test:' print >> f, ' raises = staticmethod(raises)' print >> f, ' skip = staticmethod(skip)' + print >> f, 'pytest = py.test' print >> f, backend_test_c.read() diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py --- a/pypy/tool/pytest/appsupport.py +++ b/pypy/tool/pytest/appsupport.py @@ -1,7 +1,7 @@ from inspect import CO_VARARGS, CO_VARKEYWORDS import py -from pypy.interpreter import gateway, pycode +from pypy.interpreter import gateway, pycode, typedef, baseobjspace from pypy.interpreter.error import OperationError, oefmt try: @@ -227,8 +227,42 @@ finally: frame.last_exception = old -def pypyraises(space, w_ExpectedException, w_expr, __args__): + +class W_RaisesContextManager(baseobjspace.W_Root): + # Note: this is here because of _cffi_backend/test/test_c.py + def __init__(self, space, w_ExpectedException): + self.space = space + self.w_ExpectedException = w_ExpectedException + + def enter(self): + return self + + def exit(self, w_exc_type, w_exc_value, w_traceback): + space = self.space + if space.is_none(w_exc_type): + self.report_error("no exception") + if not space.exception_match(w_exc_type, self.w_ExpectedException): + self.report_error(space.text_w(space.repr(w_exc_type))) + self.w_value = w_exc_value # for the 'value' app-level attribute + return space.w_True # suppress the exception + + def report_error(self, got): + space = self.space + raise oefmt(space.w_AssertionError, + "raises() expected %s, but got %s", + space.text_w(space.repr(self.w_ExpectedException)), + got) + +W_RaisesContextManager.typedef = typedef.TypeDef("RaisesContextManager", + __enter__ = gateway.interp2app_temp(W_RaisesContextManager.enter), + __exit__ = gateway.interp2app_temp(W_RaisesContextManager.exit), + value = typedef.interp_attrproperty_w('w_value', cls=W_RaisesContextManager) + ) + +def pypyraises(space, w_ExpectedException, w_expr=None, __args__=None): """A built-in function providing the equivalent of py.test.raises().""" + if w_expr is None: + return W_RaisesContextManager(space, w_ExpectedException) args_w, kwds_w = __args__.unpack() if space.isinstance_w(w_expr, space.w_text): if args_w: From pypy.commits at gmail.com Tue Apr 2 10:40:11 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:40:11 -0700 (PDT) Subject: [pypy-commit] cffi default: Shut down a warning from recent CPython versions: int() should Message-ID: <5ca3744b.1c69fb81.46e6f.fdcc@mx.google.com> Author: Armin Rigo Branch: Changeset: r3258:d5c083291044 Date: 2019-04-02 16:39 +0200 http://bitbucket.org/cffi/cffi/changeset/d5c083291044/ Log: Shut down a warning from recent CPython versions: int() should always return an int, not a bool diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2193,7 +2193,10 @@ return PyInt_FromLong(value); } if (cd->c_type->ct_flags & (CT_PRIMITIVE_SIGNED|CT_PRIMITIVE_UNSIGNED)) { - return convert_to_object(cd->c_data, cd->c_type); + PyObject *result = convert_to_object(cd->c_data, cd->c_type); + if (result != NULL && PyBool_Check(result)) + result = PyInt_FromLong(PyInt_AsLong(result)); + return result; } else if (cd->c_type->ct_flags & CT_PRIMITIVE_CHAR) { /*READ(cd->c_data, cd->c_type->ct_size)*/ diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -4356,3 +4356,8 @@ release(p) # no effect a += b'w' * 1000 assert a == bytearray(b"xyz" + b't' * 10 + b'v' * 100 + b'w' * 1000) + +def test_int_doesnt_give_bool(): + BBool = new_primitive_type("_Bool") + x = int(cast(BBool, 42)) + assert type(x) is int and x == 1 From pypy.commits at gmail.com Tue Apr 2 10:44:21 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:44:21 -0700 (PDT) Subject: [pypy-commit] cffi default: improve the test on py2.7 Message-ID: <5ca37545.1c69fb81.eef62.d7f6@mx.google.com> Author: Armin Rigo Branch: Changeset: r3259:dbc31afe99d0 Date: 2019-04-02 16:44 +0200 http://bitbucket.org/cffi/cffi/changeset/dbc31afe99d0/ Log: improve the test on py2.7 diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -4361,3 +4361,5 @@ BBool = new_primitive_type("_Bool") x = int(cast(BBool, 42)) assert type(x) is int and x == 1 + x = long(cast(BBool, 42)) + assert type(x) is long and x == 1 From pypy.commits at gmail.com Tue Apr 2 10:48:09 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:48:09 -0700 (PDT) Subject: [pypy-commit] cffi default: Two more cases Message-ID: <5ca37629.1c69fb81.5df77.7d67@mx.google.com> Author: Armin Rigo Branch: Changeset: r3260:e43fdc644918 Date: 2019-04-02 16:47 +0200 http://bitbucket.org/cffi/cffi/changeset/e43fdc644918/ Log: Two more cases diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -4363,3 +4363,7 @@ assert type(x) is int and x == 1 x = long(cast(BBool, 42)) assert type(x) is long and x == 1 + with pytest.raises(TypeError): + float(cast(BBool, 42)) + with pytest.raises(TypeError): + complex(cast(BBool, 42)) From pypy.commits at gmail.com Tue Apr 2 10:57:50 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Apr 2019 07:57:50 -0700 (PDT) Subject: [pypy-commit] pypy default: update to cffi/e43fdc644918 Message-ID: <5ca3786e.1c69fb81.98d26.0ea8@mx.google.com> Author: Armin Rigo Branch: Changeset: r96405:afdbea198bb5 Date: 2019-04-02 16:57 +0200 http://bitbucket.org/pypy/pypy/changeset/afdbea198bb5/ Log: update to cffi/e43fdc644918 diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -401,15 +401,22 @@ # bypass the method 'string' implemented in W_CTypePrimitive return W_CType.string(self, cdataobj, maxlen) - def convert_to_object(self, cdata): - space = self.space + def _read_bool_0_or_1(self, cdata): + """Read one byte, check it is 0 or 1, but return it as an integer""" value = ord(cdata[0]) - if value < 2: - return space.newbool(value != 0) - else: - raise oefmt(space.w_ValueError, + if value >= 2: + raise oefmt(self.space.w_ValueError, "got a _Bool of value %d, expected 0 or 1", value) + return value + + def convert_to_object(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newbool(value != 0) + + def cast_to_int(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newint(value) def unpack_list_of_int_items(self, ptr, length): return None diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -4343,3 +4343,14 @@ release(p) # no effect a += b'w' * 1000 assert a == bytearray(b"xyz" + b't' * 10 + b'v' * 100 + b'w' * 1000) + +def test_int_doesnt_give_bool(): + BBool = new_primitive_type("_Bool") + x = int(cast(BBool, 42)) + assert type(x) is int and x == 1 + x = long(cast(BBool, 42)) + assert type(x) is long and x == 1 + with pytest.raises(TypeError): + float(cast(BBool, 42)) + with pytest.raises(TypeError): + complex(cast(BBool, 42)) From pypy.commits at gmail.com Wed Apr 3 10:14:05 2019 From: pypy.commits at gmail.com (yodada) Date: Wed, 03 Apr 2019 07:14:05 -0700 (PDT) Subject: [pypy-commit] pypy record-exact-value: ( yodada, cfbolz ) Message-ID: <5ca4bfad.1c69fb81.9cccd.785c@mx.google.com> Author: Lin Cheng Branch: record-exact-value Changeset: r96406:4b4dd22d781d Date: 2019-04-03 09:01 -0400 http://bitbucket.org/pypy/pypy/changeset/4b4dd22d781d/ Log: ( yodada, cfbolz ) Branch to experiment record_exact_value From pypy.commits at gmail.com Wed Apr 3 10:14:07 2019 From: pypy.commits at gmail.com (yodada) Date: Wed, 03 Apr 2019 07:14:07 -0700 (PDT) Subject: [pypy-commit] pypy record-exact-value: ( yodada, cfbolz ) Message-ID: <5ca4bfaf.1c69fb81.c21d9.e3ad@mx.google.com> Author: Lin Cheng Branch: record-exact-value Changeset: r96407:7264752cbbf9 Date: 2019-04-03 09:25 -0400 http://bitbucket.org/pypy/pypy/changeset/7264752cbbf9/ Log: ( yodada, cfbolz ) Implemented the function in rlib and add llop diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -1193,6 +1193,36 @@ hop.exception_is_here() return hop.gendirectcall(ll_record_exact_class, v_inst, v_cls) +def record_exact_value(value, const_value): + """ + Assure the JIT that value is the same as const_value + """ + assert value is const_value + +def ll_record_exact_value(ll_value, ll_const_value): + from rpython.rlib.debug import ll_assert + from rpython.rtyper.lltypesystem.lloperation import llop + from rpython.rtyper.lltypesystem import lltype + ll_assert(ll_value is ll_const_value, "record_exact_value called with two different arguments") + llop.jit_record_exact_value(lltype.Void, ll_value, ll_const_value) + +class Entry(ExtRegistryEntry): + _about_ = record_exact_value + + def compute_result_annotation(self, s_inst, s_const_inst): + from rpython.annotator import model as annmodel + assert isinstance(s_inst, annmodel.SomeInstance) + assert isinstance(s_const_inst, annmodel.SomeInstance) + + def specialize_call(self, hop): + from rpython.rtyper.lltypesystem import lltype + from rpython.rtyper import rclass + + v_inst = hop.inputarg(hop.args_r[0], arg=0) + v_const_inst = hop.inputarg(hop.args_r[1], arg=0) + hop.exception_is_here() + return hop.gendirectcall(ll_record_exact_value, v_inst, v_const_inst) + def _jit_conditional_call(condition, function, *args): pass # special-cased below diff --git a/rpython/rlib/test/test_jit.py b/rpython/rlib/test/test_jit.py --- a/rpython/rlib/test/test_jit.py +++ b/rpython/rlib/test/test_jit.py @@ -5,7 +5,7 @@ from rpython.rlib.jit import (hint, we_are_jitted, JitDriver, elidable_promote, JitHintError, oopspec, isconstant, conditional_call, elidable, unroll_safe, dont_look_inside, conditional_call_elidable, - enter_portal_frame, leave_portal_frame) + enter_portal_frame, leave_portal_frame, record_exact_value) from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.test.tool import BaseRtypingTest from rpython.rtyper.lltypesystem import lltype @@ -115,6 +115,15 @@ def f(): pass +def test_record_exact_value(): + class A(object): + pass + a = A() + b = A() + record_exact_value(a,a) # assume not crash + with pytest.raises(AssertionError): + record_exact_value(a, b) + class TestJIT(BaseRtypingTest): def test_hint(self): def f(): @@ -341,3 +350,12 @@ leave_portal_frame() t = Translation(g, []) t.compile_c() # does not crash + + def test_record_exact_value(self): + class A(object): + pass + def g(): + a = A() + b = A() + record_exact_value(a,a) # assume not crash + self.interpret(g, []) diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -563,6 +563,9 @@ def op_jit_record_exact_class(self, *args): pass + def op_jit_record_exact_value(self, *args): + pass + def op_jit_conditional_call(self, *args): raise NotImplementedError("should not be called while not jitted") diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -456,6 +456,7 @@ 'jit_is_virtual': LLOp(canrun=True), 'jit_force_quasi_immutable': LLOp(canrun=True), 'jit_record_exact_class' : LLOp(canrun=True), + 'jit_record_exact_value' : LLOp(canrun=True), 'jit_ffi_save_result': LLOp(canrun=True), 'jit_conditional_call': LLOp(), 'jit_conditional_call_value': LLOp(), diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -636,6 +636,9 @@ def op_jit_record_exact_class(x, y): pass +def op_jit_record_exact_value(x, y): + pass + def op_jit_ffi_save_result(*args): pass From pypy.commits at gmail.com Wed Apr 3 10:14:10 2019 From: pypy.commits at gmail.com (yodada) Date: Wed, 03 Apr 2019 07:14:10 -0700 (PDT) Subject: [pypy-commit] pypy record-exact-value: ( yodada, cfbolz ) Message-ID: <5ca4bfb2.1c69fb81.7ea85.406e@mx.google.com> Author: Lin Cheng Branch: record-exact-value Changeset: r96408:61bad9af9284 Date: 2019-04-03 10:04 -0400 http://bitbucket.org/pypy/pypy/changeset/61bad9af9284/ Log: ( yodada, cfbolz ) In progress: teach the optimizer about record_exact_value Something is still wrong. diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -287,6 +287,9 @@ def rewrite_op_jit_record_exact_class(self, op): return SpaceOperation("record_exact_class", [op.args[0], op.args[1]], None) + def rewrite_op_jit_record_exact_value(self, op): + return SpaceOperation("record_exact_value", [op.args[0], op.args[1]], None) + def rewrite_op_debug_assert_not_none(self, op): if isinstance(op.args[0], Variable): return SpaceOperation('assert_not_none', [op.args[0]], None) diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -590,6 +590,10 @@ def bhimpl_record_exact_class(a, b): pass + @arguments("r", "r") + def bhimpl_record_exact_value(a, b): + pass + @arguments("i", returns="i") def bhimpl_int_copy(a): return a diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -542,6 +542,12 @@ self.make_constant_class(op.getarg(0), expectedclassbox, update_last_guard=False) + def optimize_RECORD_EXACT_VALUE(self, op): + box = op.getarg(0) + expectedconstbox = op.getarg(1) + assert isinstance(expectedconstbox, Const) + self.make_constant(box, expectedconstbox) + def optimize_GUARD_CLASS(self, op): expectedclassbox = op.getarg(1) info = self.ensure_ptr_info_arg0(op) diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py b/rpython/jit/metainterp/optimizeopt/simplify.py --- a/rpython/jit/metainterp/optimizeopt/simplify.py +++ b/rpython/jit/metainterp/optimizeopt/simplify.py @@ -48,6 +48,9 @@ def optimize_RECORD_EXACT_CLASS(self, op): pass + def optimize_RECORD_EXACT_VALUE(self, op): + pass + # def optimize_LABEL(self, op): # if not self.unroll: # descr = op.getdescr() diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -7221,6 +7221,21 @@ """ self.optimize_loop(ops, expected) + def test_record_exact_value(self): + ops = """ + [p0] + record_exact_value(p0, ConstPtr(myptr3)) + i1 = getfield_gc_i(p0, descr=valuedescr3) + escape_i(i1) + jump(p0) + """ + expected = """ + [] + escape_i(7) + jump() + """ + self.optimize_loop(ops, expected) + def test_quasi_immut(self): ops = """ [p0, p1, i0] @@ -8809,7 +8824,7 @@ i2 = int_add(i1, 1) i3 = int_le(i2, 13) guard_true(i3) [p1] - jump(p0, i2) + jump(p0, i2) """ expected = """ [p0, i1, p1] @@ -8824,7 +8839,7 @@ i2 = int_add(i1, 1) i3 = int_le(i2, 13) guard_true(i3) [p1] - jump(p0, i2, p1) + jump(p0, i2, p1) """ self.optimize_loop(ops, expected, preamble) @@ -8846,7 +8861,7 @@ escape_n(i4) setfield_gc(p0, i1, descr=valuedescr) ii = same_as_i(i1) - jump(p0, i0, i3, i1, ii) + jump(p0, i0, i3, i1, ii) """ expected = """ [p0, i0, i2, i4, i5] @@ -8887,7 +8902,7 @@ jump(i19) """ self.optimize_loop(ops, expected, expected_short=expected_short) - + def test_cached_arrayitem_write_descr(self): ops = """ diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -301,6 +301,21 @@ debug_print("record_exact_class with non-constant second argument, ignored", name, loc) + @arguments("box", "box") + def opimpl_record_exact_value(self, box, const_box): + if isinstance(const_box, Const): + self.execute(rop.RECORD_EXACT_VALUE, box, const_box) + elif have_debug_prints(): + if len(self.metainterp.framestack) >= 2: + # caller of ll_record_exact_value + name = self.metainterp.framestack[-2].jitcode.name + else: + name = self.jitcode.name + loc = self.metainterp.jitdriver_sd.warmstate.get_location_str(self.greenkey) + debug_print("record_exact_value with non-constant second argument, ignored", + name, loc) + + @arguments("box") def _opimpl_any_return(self, box): self.metainterp.finishframe(box) diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -137,7 +137,7 @@ return 'v' + str(num) if hasattr(self, '_vec_debug_info'): vecinfo = self._vec_debug_info - count = vecinfo.count + count = vecinfo.count datatype = vecinfo.datatype bytesize = vecinfo.bytesize elif self.vector == -2: @@ -322,7 +322,7 @@ "shallow copy: the returned operation is meant to be used in place of self" # XXX specialize from rpython.jit.metainterp.history import DONT_CHANGE - + if args is None: args = self.getarglist_copy() if descr is None: @@ -1140,6 +1140,7 @@ 'QUASIIMMUT_FIELD/1d/n', # [objptr], descr=SlowMutateDescr 'ASSERT_NOT_NONE/1/n', # [objptr] 'RECORD_EXACT_CLASS/2/n', # [objptr, clsptr] + 'RECORD_EXACT_VALUE/2/n', # [objptr, objptr] 'KEEPALIVE/1/n', 'SAVE_EXCEPTION/0/r', 'SAVE_EXC_CLASS/0/i', # XXX kill me diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -13,7 +13,7 @@ from rpython.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside, loop_invariant, elidable, promote, jit_debug, assert_green, AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff, - isconstant, isvirtual, set_param, record_exact_class) + isconstant, isvirtual, set_param, record_exact_class, record_exact_value) from rpython.rlib.longlong2float import float2longlong, longlong2float from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, int_force_ge_zero from rpython.rtyper.lltypesystem import lltype, rffi @@ -4038,6 +4038,32 @@ assert res1 == res2 self.check_operations_history(guard_class=1, record_exact_class=0) + def test_record_exact_value(self): + class A(object): + _immutable_fields_ = ['x'] + + a = A() + b = A() + a.x = 42 + b.x = 233 + + @dont_look_inside + def make(x): + if x > 0: + return a + else: + return b + def f(x): + inst = make(x) + if x > 0: + record_exact_value(inst, a) + else: + record_exact_value(inst, b) + return inst.x + res = self.interp_operations(f, [1]) + assert res == 42 + self.check_operations_history(record_exact_value=1) + def test_generator(self): def g(n): yield n+1 From pypy.commits at gmail.com Wed Apr 3 12:15:47 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 03 Apr 2019 09:15:47 -0700 (PDT) Subject: [pypy-commit] pypy default: add --lonepycfiles in cpython_differences Message-ID: <5ca4dc33.1c69fb81.63afa.b766@mx.google.com> Author: Armin Rigo Branch: Changeset: r96409:570adebe6118 Date: 2019-04-03 18:14 +0200 http://bitbucket.org/pypy/pypy/changeset/570adebe6118/ Log: add --lonepycfiles in cpython_differences diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -485,6 +485,15 @@ * Dictionaries and sets are ordered on PyPy. On CPython < 3.6 they are not; on CPython >= 3.6 dictionaries (but not sets) are ordered. +* PyPy2 refuses to load lone ``.pyc`` files, i.e. ``.pyc`` files that are + still there after you deleted the ``.py`` file. PyPy3 instead behaves like + CPython. We could be amenable to fix this difference in PyPy2: the current + version reflects `our annoyance`__ with this detail of CPython, which bit + us too often while developing PyPy. (It is as easy as passing the + ``--lonepycfile`` flag when translating PyPy, if you really need it.) + +.. __: https://stackoverflow.com/a/55499713/1556290 + .. _extension-modules: From pypy.commits at gmail.com Wed Apr 3 19:01:43 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 03 Apr 2019 16:01:43 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Move new_ref_dict() to rpython.jit.metainterp.history Message-ID: <5ca53b57.1c69fb81.65f88.36cd@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96413:e6ca265bbc8a Date: 2019-04-03 20:28 +0100 http://bitbucket.org/pypy/pypy/changeset/e6ca265bbc8a/ Log: Move new_ref_dict() to rpython.jit.metainterp.history 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 @@ -1,18 +1,15 @@ from rpython.rlib import rgc -from rpython.rlib.objectmodel import we_are_translated, r_dict, always_inline +from rpython.rlib.objectmodel import we_are_translated, always_inline from rpython.rlib.rarithmetic import ovfcheck, highest_bit from rpython.rtyper.lltypesystem import llmemory, lltype, rstr from rpython.rtyper.annlowlevel import cast_instance_to_gcref -from rpython.jit.metainterp import history -from rpython.jit.metainterp.history import ConstInt, ConstPtr +from rpython.jit.metainterp.history import ( + ConstInt, ConstPtr, JitCellToken, new_ref_dict) from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers -from rpython.jit.metainterp.typesystem import rd_eq, rd_hash from rpython.jit.codewriter import heaptracker from rpython.jit.backend.llsupport.symbolic import (WORD, get_field_token, get_array_token) -from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr,\ - FLAG_POINTER -from rpython.jit.metainterp.history import JitCellToken +from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr from rpython.jit.backend.llsupport.descr import (unpack_arraydescr, unpack_fielddescr, unpack_interiorfielddescr) from rpython.rtyper.lltypesystem.lloperation import llop @@ -608,11 +605,11 @@ def handle_call_assembler(self, op): descrs = self.gc_ll_descr.getframedescrs(self.cpu) loop_token = op.getdescr() - assert isinstance(loop_token, history.JitCellToken) + assert isinstance(loop_token, JitCellToken) jfi = loop_token.compiled_loop_token.frame_info llfi = heaptracker.adr2int(llmemory.cast_ptr_to_adr(jfi)) frame = self.gen_malloc_frame(llfi) - self.emit_setfield(frame, history.ConstInt(llfi), + self.emit_setfield(frame, ConstInt(llfi), descr=descrs.jf_frame_info) arglist = op.getarglist() index_list = loop_token.compiled_loop_token._ll_initial_locs @@ -948,7 +945,7 @@ def _gcref_index(self, gcref): if self.gcrefs_map is None: - self.gcrefs_map = r_dict(rd_eq, rd_hash) + self.gcrefs_map = new_ref_dict() try: return self.gcrefs_map[gcref] except KeyError: diff --git a/rpython/jit/backend/test/jitlog_test.py b/rpython/jit/backend/test/jitlog_test.py --- a/rpython/jit/backend/test/jitlog_test.py +++ b/rpython/jit/backend/test/jitlog_test.py @@ -3,7 +3,6 @@ from rpython.rlib import debug from rpython.jit.tool.oparser import pure_parse from rpython.jit.metainterp import logger -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.rjitlog import rjitlog as jl from StringIO import StringIO from rpython.jit.metainterp.optimizeopt.util import equaloplists 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 @@ -3,8 +3,8 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.annlowlevel import ( cast_gcref_to_instance, cast_instance_to_gcref) -from rpython.rlib.objectmodel import we_are_translated, Symbolic -from rpython.rlib.objectmodel import compute_unique_id, specialize +from rpython.rlib.objectmodel import ( + we_are_translated, Symbolic, compute_unique_id, specialize, r_dict) from rpython.rlib.rarithmetic import r_int64, is_valid_int from rpython.rlib.rarithmetic import LONG_BIT, intmask, r_uint from rpython.rlib.jit import Counters @@ -386,6 +386,20 @@ return result _const_ptr_for_unicode = {} +# A dict whose keys are refs (like the .value of ConstPtr). +# It is an r_dict. Note that NULL is not allowed as a key. + at specialize.call_location() +def new_ref_dict(): + return r_dict(rd_eq, rd_hash, simple_hash_eq=True) + +def rd_eq(ref1, ref2): + return ref1 == ref2 + +def rd_hash(ref): + assert ref + return lltype.identityhash(ref) + + # ____________________________________________________________ # The JitCellToken class is the root of a tree of traces. Each branch ends diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -6,14 +6,14 @@ Snapshot index for guards points to snapshot stored in _snapshots of trace """ -from rpython.jit.metainterp.history import ConstInt, Const, ConstFloat, ConstPtr +from rpython.jit.metainterp.history import ( + ConstInt, Const, ConstFloat, ConstPtr, new_ref_dict) from rpython.jit.metainterp.resoperation import AbstractResOp, AbstractInputArg,\ ResOperation, oparity, rop, opwithdescr, GuardResOp, IntOp, FloatOp, RefOp,\ opclasses from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.rtyper.lltypesystem import rffi, lltype, llmemory -from rpython.jit.metainterp.typesystem import llhelper TAGINT, TAGCONSTPTR, TAGCONSTOTHER, TAGBOX = range(4) TAGMASK = 0x3 @@ -179,7 +179,7 @@ if opwithdescr[opnum]: descr_index = self._next() if rop.is_guard(opnum): - update_liveranges(self.trace._snapshots[descr_index], index, + update_liveranges(self.trace._snapshots[descr_index], index, liveranges) if opclasses[opnum].type != 'v': return index + 1 @@ -274,7 +274,7 @@ self._consts_ptr = 0 self._descrs = [None] self._refs = [lltype.nullptr(llmemory.GCREF.TO)] - self._refs_dict = llhelper.new_ref_dict_3() + self._refs_dict = new_ref_dict() self._bigints = [] self._bigints_dict = {} self._floats = [] @@ -304,7 +304,7 @@ assert not self.tag_overflow self._bigints_dict = {} - self._refs_dict = llhelper.new_ref_dict_3() + self._refs_dict = new_ref_dict() debug_start("jit-trace-done") debug_print("trace length: " + str(self._pos)) debug_print(" total snapshots: " + str(self._total_snapshots)) diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -3,7 +3,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.optimizeopt.util import args_dict -from rpython.jit.metainterp.history import Const, ConstInt +from rpython.jit.metainterp.history import Const, ConstInt, new_ref_dict from rpython.jit.metainterp.jitexc import JitException from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method @@ -14,7 +14,7 @@ GuardResOp from rpython.rlib.objectmodel import we_are_translated from rpython.jit.metainterp.optimizeopt import info - + class BogusImmutableField(JitException): @@ -97,7 +97,7 @@ # need any _lazy_set: the heap value is already right. # Note that this may reset to None a non-None lazy_set, # cancelling its previous effects with no side effect. - + # Now, we have to force the item in the short preamble self._getfield(structinfo, op.getdescr(), optheap) self._lazy_set = None @@ -251,7 +251,7 @@ def setup(self): self.optimizer.optheap = self # mapping const value -> info corresponding to it's heap cache - self.const_infos = self.optimizer.cpu.ts.new_ref_dict() + self.const_infos = new_ref_dict() def flush(self): self.cached_dict_reads.clear() diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -1,7 +1,7 @@ from rpython.jit.metainterp import jitprof, resume, compile from rpython.jit.metainterp.executor import execute_nonspec_const from rpython.jit.metainterp.history import ( - Const, ConstInt, ConstPtr, CONST_NULL) + Const, ConstInt, ConstPtr, CONST_NULL, new_ref_dict) from rpython.jit.metainterp.optimizeopt.intutils import IntBound,\ ConstIntBound, MININT, MAXINT, IntUnbounded from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method @@ -9,7 +9,6 @@ OpHelpers from rpython.jit.metainterp.optimizeopt import info from rpython.jit.metainterp.optimize import InvalidLoop -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.objectmodel import specialize, we_are_translated from rpython.rlib.debug import debug_print from rpython.rtyper import rclass @@ -272,7 +271,7 @@ self.metainterp_sd = metainterp_sd self.jitdriver_sd = jitdriver_sd self.cpu = metainterp_sd.cpu - self.interned_refs = self.cpu.ts.new_ref_dict() + self.interned_refs = new_ref_dict() self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd) self.pendingfields = None # set temporarily to a list, normally by # heap.py, as we're about to generate a guard diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py --- a/rpython/jit/metainterp/optimizeopt/vstring.py +++ b/rpython/jit/metainterp/optimizeopt/vstring.py @@ -2,9 +2,8 @@ from rpython.jit.metainterp.history import (Const, ConstInt, ConstPtr, get_const_ptr_for_string, get_const_ptr_for_unicode, REF, INT, DONT_CHANGE, CONST_NULL) -from rpython.jit.metainterp.optimizeopt import optimizer -from rpython.jit.metainterp.optimizeopt.optimizer import CONST_0, CONST_1 -from rpython.jit.metainterp.optimizeopt.optimizer import llhelper, REMOVED +from rpython.jit.metainterp.optimizeopt.optimizer import ( + CONST_0, CONST_1, REMOVED, Optimization) from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.jit.metainterp.optimizeopt import info @@ -47,7 +46,6 @@ # ____________________________________________________________ - class StrPtrInfo(info.AbstractVirtualPtrInfo): #_attrs_ = ('length', 'lenbound', 'lgtop', 'mode', '_cached_vinfo', '_is_virtual') @@ -72,7 +70,7 @@ @specialize.arg(2) def get_constant_string_spec(self, string_optimizer, mode): - return None # can't be constant + return None # can't be constant def force_box(self, op, optforce): if not self.is_virtual(): @@ -196,8 +194,8 @@ def initialize_forced_string(self, op, string_optimizer, targetbox, offsetbox, mode): for i in range(len(self._chars)): - assert not isinstance(targetbox, Const) # ConstPtr never makes sense - charbox = self.strgetitem(i) # can't be virtual + assert not isinstance(targetbox, Const) # ConstPtr never makes sense + charbox = self.strgetitem(i) # can't be virtual if charbox is not None: op = ResOperation(mode.STRSETITEM, [targetbox, offsetbox, @@ -247,7 +245,7 @@ length = vlength.getint() assert start >= 0 assert length >= 0 - return s1[start : start + length] + return s1[start: start + length] return None def getstrlen(self, op, string_optimizer, mode): @@ -353,7 +351,7 @@ charbox = string_optimizer.strgetitem(None, srcbox, srcoffsetbox, mode) srcoffsetbox = _int_add(string_optimizer, srcoffsetbox, CONST_1) - assert not isinstance(targetbox, Const)# ConstPtr never makes sense + assert not isinstance(targetbox, Const) # ConstPtr never makes sense string_optimizer.emit_extra(ResOperation(mode.STRSETITEM, [targetbox, offsetbox, charbox])) offsetbox = _int_add(string_optimizer, offsetbox, CONST_1) @@ -412,7 +410,7 @@ return resbox -class OptString(optimizer.Optimization): +class OptString(Optimization): "Handling of strings and unicodes." def setup(self): @@ -444,6 +442,7 @@ def optimize_NEWSTR(self, op): return self._optimize_NEWSTR(op, mode_string) + def optimize_NEWUNICODE(self, op): return self._optimize_NEWSTR(op, mode_unicode) @@ -480,6 +479,7 @@ def optimize_STRGETITEM(self, op): return self._optimize_STRGETITEM(op, mode_string) + def optimize_UNICODEGETITEM(self, op): return self._optimize_STRGETITEM(op, mode_unicode) @@ -522,6 +522,7 @@ def optimize_STRLEN(self, op): return self._optimize_STRLEN(op, mode_string) + def optimize_UNICODELEN(self, op): return self._optimize_STRLEN(op, mode_unicode) @@ -537,6 +538,7 @@ def optimize_STRHASH(self, op): return self._optimize_STRHASH(op, mode_string) + def optimize_UNICODEHASH(self, op): return self._optimize_STRHASH(op, mode_unicode) @@ -761,18 +763,15 @@ l1box = i1.getstrlen(arg1, self, mode) if isinstance(l1box, ConstInt) and l1box.value == 1: # comparing two single chars - vchar1 = self.strgetitem(None, arg1, optimizer.CONST_0, - mode) - vchar2 = self.strgetitem(None, arg2, optimizer.CONST_0, - mode) + vchar1 = self.strgetitem(None, arg1, CONST_0, mode) + vchar2 = self.strgetitem(None, arg2, CONST_0, mode) seo = self.optimizer.send_extra_operation op = self.optimizer.replace_op_with(resultop, rop.INT_EQ, [vchar1, vchar2], descr=DONT_CHANGE) seo(op) return True, None if isinstance(i1, VStringSliceInfo): - vchar = self.strgetitem(None, arg2, optimizer.CONST_0, - mode) + vchar = self.strgetitem(None, arg2, CONST_0, mode) do = EffectInfo.OS_STREQ_SLICE_CHAR return True, self.generate_modified_call(do, [i1.s, i1.start, i1.lgtop, vchar], @@ -801,7 +800,7 @@ l2info = self.getintbound(l2box) if l2info.is_constant(): if l2info.getint() == 1: - vchar = self.strgetitem(None, arg2, optimizer.CONST_0, mode) + vchar = self.strgetitem(None, arg2, CONST_0, mode) if i1 and i1.is_nonnull(): do = EffectInfo.OS_STREQ_NONNULL_CHAR else: @@ -832,8 +831,8 @@ isinstance(l2box, ConstInt) and l1box.getint() == l2box.getint() == 1): # comparing two single chars - char1 = self.strgetitem(None, op.getarg(1), optimizer.CONST_0, mode) - char2 = self.strgetitem(None, op.getarg(2), optimizer.CONST_0, mode) + char1 = self.strgetitem(None, op.getarg(1), CONST_0, mode) + char2 = self.strgetitem(None, op.getarg(2), CONST_0, mode) seo = self.optimizer.send_extra_operation op = self.replace_op_with(op, rop.INT_SUB, [char1, char2], descr=DONT_CHANGE) diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -2,7 +2,8 @@ from rpython.jit.metainterp import jitprof from rpython.jit.metainterp.history import ( Const, ConstInt, ConstPtr, getkind, INT, REF, FLOAT, CONST_NULL, - AbstractDescr, IntFrontendOp, RefFrontendOp, FloatFrontendOp) + AbstractDescr, IntFrontendOp, RefFrontendOp, FloatFrontendOp, + new_ref_dict) from rpython.jit.metainterp.resoperation import rop from rpython.rlib import rarithmetic, rstack from rpython.rlib.objectmodel import (we_are_translated, specialize, @@ -177,7 +178,7 @@ self.cpu = metainterp_sd.cpu self.consts = [] self.large_ints = {} - self.refs = self.cpu.ts.new_ref_dict_2() + self.refs = new_ref_dict() self.cached_boxes = {} self.cached_virtuals = {} diff --git a/rpython/jit/metainterp/test/test_history.py b/rpython/jit/metainterp/test/test_history.py --- a/rpython/jit/metainterp/test/test_history.py +++ b/rpython/jit/metainterp/test/test_history.py @@ -70,6 +70,30 @@ f.set_position(6519) assert f.get_position() == 6519 +def fresh_ref(): + S = lltype.GcStruct('S') + s = lltype.malloc(S) + return lltype.cast_opaque_ptr(llmemory.GCREF, s) + +def duplicate_ref(x): + s = x._obj.container._as_ptr() + return lltype.cast_opaque_ptr(llmemory.GCREF, s) + +def test_ref_dict(): + d = new_ref_dict() + ref1 = fresh_ref() + ref2 = fresh_ref() + ref3 = fresh_ref() + d[ref1] = 123 + d[ref2] = 456 + d[ref3] = 789 + ref1b = duplicate_ref(ref1) + ref2b = duplicate_ref(ref2) + ref3b = duplicate_ref(ref3) + assert d[ref1b] == 123 + assert d[ref2b] == 456 + assert d[ref3b] == 789 + class TestZTranslated(StandaloneTests): def test_ztranslated_same_constant_float(self): def fn(args): diff --git a/rpython/jit/metainterp/test/test_typesystem.py b/rpython/jit/metainterp/test/test_typesystem.py deleted file mode 100644 --- a/rpython/jit/metainterp/test/test_typesystem.py +++ /dev/null @@ -1,36 +0,0 @@ -from rpython.jit.metainterp import typesystem -from rpython.rtyper.lltypesystem import lltype, llmemory - - -class TypeSystemTests(object): - - def test_ref_dict(self): - d = self.helper.new_ref_dict() - ref1 = self.fresh_ref() - ref2 = self.fresh_ref() - ref3 = self.fresh_ref() - d[ref1] = 123 - d[ref2] = 456 - d[ref3] = 789 - ref1b = self.duplicate_ref(ref1) - ref2b = self.duplicate_ref(ref2) - ref3b = self.duplicate_ref(ref3) - assert d[ref1b] == 123 - assert d[ref2b] == 456 - assert d[ref3b] == 789 - - -class TestLLtype(TypeSystemTests): - helper = typesystem.llhelper - - def fresh_ref(self): - S = lltype.GcStruct('S') - s = lltype.malloc(S) - return lltype.cast_opaque_ptr(llmemory.GCREF, s) - - def duplicate_ref(self, x): - s = x._obj.container._as_ptr() - return lltype.cast_opaque_ptr(llmemory.GCREF, s) - - def null_ref(self): - return lltype.nullptr(llmemory.GCREF.TO) diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -19,23 +19,4 @@ cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(heaptracker.adr2int(cls)) - # A dict whose keys are refs (like the .value of BoxPtr). - # It is an r_dict on lltype. Two copies, to avoid conflicts with - # the value type. Note that NULL is not allowed as a key. - def new_ref_dict(self): - return r_dict(rd_eq, rd_hash, simple_hash_eq=True) - - def new_ref_dict_2(self): - return r_dict(rd_eq, rd_hash, simple_hash_eq=True) - - def new_ref_dict_3(self): - return r_dict(rd_eq, rd_hash, simple_hash_eq=True) - -def rd_eq(ref1, ref2): - return ref1 == ref2 - -def rd_hash(ref): - assert ref - return lltype.identityhash(ref) - llhelper = LLTypeHelper() From pypy.commits at gmail.com Wed Apr 3 21:31:19 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 03 Apr 2019 18:31:19 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: clean up uses of AbstractCPU and random stylistic issues, including a duplicated test Message-ID: <5ca55e67.1c69fb81.3cd8.5d51@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96414:8c0194bc5160 Date: 2019-04-04 01:51 +0100 http://bitbucket.org/pypy/pypy/changeset/8c0194bc5160/ Log: clean up uses of AbstractCPU and random stylistic issues, including a duplicated test diff --git a/rpython/jit/backend/test/jitlog_test.py b/rpython/jit/backend/test/jitlog_test.py --- a/rpython/jit/backend/test/jitlog_test.py +++ b/rpython/jit/backend/test/jitlog_test.py @@ -1,18 +1,8 @@ -import re import os -from rpython.rlib import debug -from rpython.jit.tool.oparser import pure_parse -from rpython.jit.metainterp import logger from rpython.rlib.rjitlog import rjitlog as jl -from StringIO import StringIO -from rpython.jit.metainterp.optimizeopt.util import equaloplists -from rpython.jit.metainterp.history import AbstractDescr, JitCellToken, BasicFailDescr, BasicFinalDescr -from rpython.jit.backend.model import AbstractCPU from rpython.rlib.jit import JitDriver -from rpython.rlib.objectmodel import always_inline from rpython.jit.metainterp.test.support import LLJitMixin from rpython.rlib.rjitlog import rjitlog -import tempfile class LoggerTest(LLJitMixin): @@ -33,7 +23,7 @@ file = tmpdir.join('jitlog') monkeypatch.setenv("JITLOG", file.strpath) f = self.run_sample_loop(None) - self.meta_interp(f, [10,0]) + self.meta_interp(f, [10, 0]) assert os.path.exists(file.strpath) with file.open('rb') as fd: # check the file header @@ -45,28 +35,16 @@ monkeypatch.setattr(jl, 'JITLOG_VERSION_16BIT_LE', '\xff\xfe') monkeypatch.setenv("JITLOG", file.strpath) f = self.run_sample_loop(None) - self.meta_interp(f, [10,0]) + self.meta_interp(f, [10, 0]) assert os.path.exists(file.strpath) with file.open('rb') as fd: # check the file header assert fd.read(3) == jl.MARK_JITLOG_HEADER + '\xff\xfe' assert len(fd.read()) > 0 - def test_version(self, monkeypatch, tmpdir): - file = tmpdir.join('jitlog') - monkeypatch.setattr(jl, 'JITLOG_VERSION_16BIT_LE', '\xff\xfe') - monkeypatch.setenv("JITLOG", file.strpath) - f = self.run_sample_loop(None) - self.meta_interp(f, [10,0]) - assert os.path.exists(file.strpath) - with file.open('rb') as fd: - # check the file header - assert fd.read(3) == jl.MARK_JITLOG_HEADER + '\xff\xfe' - assert len(fd.read()) > 0 - - def run_sample_loop(self, func, myjitdriver = None): + def run_sample_loop(self, func, myjitdriver=None): if not myjitdriver: - myjitdriver = JitDriver(greens = [], reds = 'auto') + myjitdriver = JitDriver(greens=[], reds='auto') def f(y, x): res = 0 if func: diff --git a/rpython/jit/metainterp/test/test_logger.py b/rpython/jit/metainterp/test/test_logger.py --- a/rpython/jit/metainterp/test/test_logger.py +++ b/rpython/jit/metainterp/test/test_logger.py @@ -6,7 +6,6 @@ from rpython.jit.metainterp.optimizeopt.util import equaloplists from rpython.jit.metainterp.history import ( AbstractDescr, JitCellToken, BasicFailDescr, BasicFinalDescr) -from rpython.jit.backend.model import AbstractCPU class Descr(AbstractDescr): @@ -19,8 +18,10 @@ for arg in args: print >> log_stream, arg, print >> log_stream + def debug_start(self, *args): pass + def debug_stop(self, *args): pass try: @@ -55,7 +56,6 @@ get_location_str = staticmethod(lambda args: "dupa") class FakeMetaInterpSd: - cpu = AbstractCPU() jitdrivers_sd = [FakeJitDriver()] def get_name_from_address(self, addr): return 'Name' diff --git a/rpython/rlib/rjitlog/test/test_jitlog.py b/rpython/rlib/rjitlog/test/test_jitlog.py --- a/rpython/rlib/rjitlog/test/test_jitlog.py +++ b/rpython/rlib/rjitlog/test/test_jitlog.py @@ -1,10 +1,7 @@ import pytest import sys -from rpython.jit.tool.oparser import pure_parse -from rpython.jit.metainterp.optimizeopt.util import equaloplists from rpython.jit.metainterp.resoperation import ResOperation, rop -from rpython.jit.backend.model import AbstractCPU -from rpython.jit.metainterp.history import ConstInt, ConstPtr +from rpython.jit.metainterp.history import ConstInt from rpython.rlib.rjitlog import rjitlog as jl from rpython.jit.metainterp.history import AbstractDescr from rpython.rlib.objectmodel import compute_unique_id @@ -41,7 +38,6 @@ class FakeMetaInterpSd: - cpu = AbstractCPU() jitdrivers_sd = [FakeJitDriver()] def get_name_from_address(self, addr): return 'Name' From pypy.commits at gmail.com Thu Apr 4 19:55:58 2019 From: pypy.commits at gmail.com (rlamy) Date: Thu, 04 Apr 2019 16:55:58 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: remove unused argument from test helper Message-ID: <5ca6998e.1c69fb81.4a24c.68fc@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96415:ec67059fa49e Date: 2019-04-04 17:45 +0100 http://bitbucket.org/pypy/pypy/changeset/ec67059fa49e/ Log: remove unused argument from test helper diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py --- a/rpython/jit/backend/test/test_ll_random.py +++ b/rpython/jit/backend/test/test_ll_random.py @@ -218,7 +218,7 @@ # ____________________________________________________________ -def ConstAddr(addr, cpu): +def ConstAddr(addr): return ConstInt(heaptracker.adr2int(addr)) class GuardClassOperation(test_random.GuardOperation): @@ -235,7 +235,7 @@ v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable = S._hints['vtable']._as_ptr() vtable2 = S2._hints['vtable']._as_ptr() - c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), builder.cpu) + c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2)) op = ResOperation(self.opnum, [v, c_vtable2], None) return op, (vtable == vtable2) @@ -249,8 +249,7 @@ builder.loop.operations.append(op) v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable2 = S2._hints['vtable']._as_ptr() - c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), - builder.cpu) + c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2)) op = ResOperation(self.opnum, [op, c_vtable2], None) return op, False @@ -616,7 +615,7 @@ RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) @@ -633,12 +632,12 @@ RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) - exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) + exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(builder.subset_of_intvars(r)) @@ -655,11 +654,11 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) - exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) + exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(fail_subset) @@ -672,13 +671,13 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) - op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) + op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op @@ -691,7 +690,7 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) @@ -699,10 +698,10 @@ _, vtableptr = builder.get_random_structure_type_and_vtable(r) if vtableptr != exc: break - other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) + other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], descr=builder.getfaildescr()) - op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) + op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op @@ -735,7 +734,7 @@ # TP = lltype.FuncType([lltype.Signed] * len(subset), RESULT_TYPE) ptr = llhelper(lltype.Ptr(TP), call_me) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) args = [v_cond, c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py --- a/rpython/jit/metainterp/test/test_resume.py +++ b/rpython/jit/metainterp/test/test_resume.py @@ -638,12 +638,12 @@ pass fakeoptimizer = FakeOptimizer_VirtualValue() -def ConstAddr(addr, cpu): # compatibility +def ConstAddr(addr): # compatibility return ConstInt(heaptracker.adr2int(addr)) def virtual_value(keybox, value, next): - vv = VirtualValue(fakeoptimizer, ConstAddr(LLtypeMixin.node_vtable_adr, - LLtypeMixin.cpu), keybox) + vv = VirtualValue( + fakeoptimizer, ConstAddr(LLtypeMixin.node_vtable_adr), keybox) if not isinstance(next, OptValue): next = OptValue(next) vv.setfield(LLtypeMixin.valuedescr, OptValue(value)) @@ -1212,13 +1212,13 @@ modifier.vfieldboxes = {} vdescr = LLtypeMixin.nodesize2 - ca = ConstAddr(LLtypeMixin.node_vtable_adr2, LLtypeMixin.cpu) + ca = ConstAddr(LLtypeMixin.node_vtable_adr2) v4 = info.InstancePtrInfo(vdescr, ca, True) b4s.set_forwarded(v4) v4.setfield(LLtypeMixin.nextdescr, ca, b2s) v4.setfield(LLtypeMixin.valuedescr, ca, b3s) v4.setfield(LLtypeMixin.otherdescr, ca, b5s) - ca = ConstAddr(LLtypeMixin.node_vtable_adr, LLtypeMixin.cpu) + ca = ConstAddr(LLtypeMixin.node_vtable_adr) v2 = info.InstancePtrInfo(LLtypeMixin.nodesize, ca, True) v2.setfield(LLtypeMixin.nextdescr, b4s, ca) v2.setfield(LLtypeMixin.valuedescr, c1s, ca) From pypy.commits at gmail.com Thu Apr 4 19:56:00 2019 From: pypy.commits at gmail.com (rlamy) Date: Thu, 04 Apr 2019 16:56:00 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: move some utility functions from heaptracker to rpython.jit.metainterp.support Message-ID: <5ca69990.1c69fb81.509b6.55d3@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96416:12b8316618ca Date: 2019-04-05 00:52 +0100 http://bitbucket.org/pypy/pypy/changeset/12b8316618ca/ Log: move some utility functions from heaptracker to rpython.jit.metainterp.support diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -9,6 +9,7 @@ from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.optimizeopt import intbounds from rpython.jit.metainterp.optimize import SpeculativeError +from rpython.jit.metainterp.support import adr2int, int2adr, int_signext from rpython.jit.codewriter import longlong, heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo @@ -136,7 +137,7 @@ if self._vtable is Ellipsis: self._vtable = heaptracker.get_vtable_for_gcstruct(self._runner, self.S) - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(self._vtable)) + return adr2int(llmemory.cast_ptr_to_adr(self._vtable)) def is_immutable(self): return heaptracker.is_immutable_struct(self.S) @@ -877,7 +878,7 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return heaptracker.adr2int(result_adr) + return adr2int(result_adr) # vector operations vector_arith_code = """ @@ -977,7 +978,7 @@ bh_vec_expand_i = _bh_vec_expand def bh_vec_int_signext(self, vx, ext, count): - return [heaptracker.int_signext(_vx, ext) for _vx in vx] + return [int_signext(_vx, ext) for _vx in vx] def build_load(func): def load(self, struct, offset, scale, disp, descr, _count): @@ -1551,7 +1552,7 @@ return res def execute_restore_exception(self, descr, kls, e): - kls = heaptracker.int2adr(kls) + kls = int2adr(kls) if e: value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, e) assert llmemory.cast_ptr_to_adr(value.typeptr) == kls diff --git a/rpython/jit/backend/llgraph/support.py b/rpython/jit/backend/llgraph/support.py --- a/rpython/jit/backend/llgraph/support.py +++ b/rpython/jit/backend/llgraph/support.py @@ -1,7 +1,6 @@ from rpython.jit.codewriter import longlong -from rpython.jit.codewriter import heaptracker - +from rpython.jit.metainterp.support import adr2int from rpython.jit.metainterp.history import getkind from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint @@ -20,9 +19,9 @@ def cast_to_int(x): TP = lltype.typeOf(x) if isinstance(TP, lltype.Ptr): - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + return adr2int(llmemory.cast_ptr_to_adr(x)) if TP == llmemory.Address: - return heaptracker.adr2int(x) + return adr2int(x) if TP is lltype.SingleFloat: return longlong.singlefloat2int(x) return lltype.cast_primitive(lltype.Signed, x) @@ -82,7 +81,7 @@ return longlong.int2singlefloat(x) else: if lltype.typeOf(x) == llmemory.Address: - x = heaptracker.adr2int(x) + x = adr2int(x) return lltype.cast_primitive(TYPE, x) def cast_from_ptr(TYPE, x): diff --git a/rpython/jit/backend/llgraph/test/test_llgraph.py b/rpython/jit/backend/llgraph/test/test_llgraph.py --- a/rpython/jit/backend/llgraph/test/test_llgraph.py +++ b/rpython/jit/backend/llgraph/test/test_llgraph.py @@ -1,6 +1,4 @@ import py -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.jit.codewriter import heaptracker from rpython.jit.backend.test.runner_test import LLtypeBackendTest from rpython.jit.backend.llgraph.runner import LLGraphCPU @@ -17,16 +15,3 @@ def test_call_release_gil_variable_function_and_arguments(self): py.test.skip("the arguments seem not correctly casted") - - -def test_cast_adr_to_int_and_back(): - X = lltype.Struct('X', ('foo', lltype.Signed)) - x = lltype.malloc(X, immortal=True) - x.foo = 42 - a = llmemory.cast_ptr_to_adr(x) - i = heaptracker.adr2int(a) - assert lltype.typeOf(i) is lltype.Signed - a2 = heaptracker.int2adr(i) - assert llmemory.cast_adr_to_ptr(a2, lltype.Ptr(X)) == x - assert heaptracker.adr2int(llmemory.NULL) == 0 - assert heaptracker.int2adr(0) == llmemory.NULL diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py --- a/rpython/jit/backend/llsupport/descr.py +++ b/rpython/jit/backend/llsupport/descr.py @@ -4,6 +4,7 @@ from rpython.jit.backend.llsupport import symbolic, support from rpython.jit.metainterp.history import AbstractDescr, getkind, FLOAT, INT from rpython.jit.metainterp import history +from rpython.jit.metainterp.support import adr2int, int2adr from rpython.jit.codewriter import heaptracker, longlong from rpython.jit.codewriter.longlong import is_longlong from rpython.jit.metainterp.optimizeopt import intbounds @@ -84,7 +85,7 @@ def is_valid_class_for(self, struct): objptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) cls = llmemory.cast_adr_to_ptr( - heaptracker.int2adr(self.get_vtable()), + int2adr(self.get_vtable()), lltype.Ptr(rclass.OBJECT_VTABLE)) # this first comparison is necessary, since we want to make sure # that vtable for JitVirtualRef is the same without actually reading @@ -95,7 +96,7 @@ return self.immutable_flag def get_vtable(self): - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(self.vtable)) + return adr2int(llmemory.cast_ptr_to_adr(self.vtable)) def get_type_id(self): assert self.tid diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -11,6 +11,7 @@ from rpython.jit.codewriter import heaptracker from rpython.jit.metainterp.history import ConstPtr, AbstractDescr, ConstInt from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.metainterp.support import adr2int from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr, FieldDescr @@ -66,7 +67,7 @@ @specialize.arg(1) def get_malloc_fn_addr(self, funcname): ll_func = self.get_malloc_fn(funcname) - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(ll_func)) + return adr2int(llmemory.cast_ptr_to_adr(ll_func)) def _freeze_(self): return True diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -8,7 +8,8 @@ from rpython.rlib.objectmodel import we_are_translated, specialize, compute_hash from rpython.jit.metainterp import history, compile from rpython.jit.metainterp.optimize import SpeculativeError -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.metainterp.support import adr2int +from rpython.jit.codewriter import longlong from rpython.jit.backend.model import AbstractCPU from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes @@ -158,7 +159,7 @@ graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() - self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + self.realloc_frame = adr2int(llmemory.cast_ptr_to_adr(fptr)) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame_crash) @@ -170,7 +171,7 @@ graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() - self.realloc_frame_crash = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + self.realloc_frame_crash = adr2int(llmemory.cast_ptr_to_adr(fptr)) def _setup_exception_handling_untranslated(self): # for running un-translated only, all exceptions occurring in the @@ -207,11 +208,11 @@ def pos_exception(): addr = llop.get_exception_addr(llmemory.Address) - return heaptracker.adr2int(addr) + return adr2int(addr) def pos_exc_value(): addr = llop.get_exc_value_addr(llmemory.Address) - return heaptracker.adr2int(addr) + return adr2int(addr) from rpython.rlib import rstack @@ -775,7 +776,7 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return heaptracker.adr2int(result_adr) + return adr2int(result_adr) def bh_new_array(self, length, arraydescr): return self.gc_ll_descr.gc_malloc_array(length, arraydescr) 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 @@ -6,7 +6,7 @@ from rpython.jit.metainterp.history import ( ConstInt, ConstPtr, JitCellToken, new_ref_dict) from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers -from rpython.jit.codewriter import heaptracker +from rpython.jit.metainterp.support import adr2int from rpython.jit.backend.llsupport.symbolic import (WORD, get_field_token, get_array_token) from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr @@ -607,7 +607,7 @@ loop_token = op.getdescr() assert isinstance(loop_token, JitCellToken) jfi = loop_token.compiled_loop_token.frame_info - llfi = heaptracker.adr2int(llmemory.cast_ptr_to_adr(jfi)) + llfi = adr2int(llmemory.cast_ptr_to_adr(jfi)) frame = self.gen_malloc_frame(llfi) self.emit_setfield(frame, ConstInt(llfi), descr=descrs.jf_frame_info) diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -2,11 +2,12 @@ from rpython.jit.metainterp.history import BasicFinalDescr,\ JitCellToken, ConstInt, ConstFloat from rpython.jit.metainterp.resoperation import rop, InputArgInt, InputArgFloat +from rpython.jit.metainterp.support import adr2int from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.backend.detect_cpu import getcpuclass from rpython.jit.backend.test.runner_test import Runner import py @@ -50,7 +51,7 @@ @classmethod def get_funcbox(cls, cpu, func_ptr): addr = llmemory.cast_ptr_to_adr(func_ptr) - return ConstInt(heaptracker.adr2int(addr)) + return ConstInt(adr2int(addr)) def test_call_aligned_with_spilled_values(self): cpu = self.cpu diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -11,13 +11,14 @@ from rpython.jit.metainterp.resoperation import ( ResOperation, rop, InputArgInt, InputArgFloat, InputArgRef) from rpython.jit.metainterp.executor import wrap_constant +from rpython.jit.metainterp.support import adr2int, int_signext from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi from rpython.rtyper import rclass from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.llinterp import LLException -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.rlib import longlong2float from rpython.rlib.rarithmetic import intmask, is_valid_int from rpython.jit.backend.detect_cpu import autodetect @@ -1846,7 +1847,7 @@ @classmethod def get_funcbox(cls, cpu, func_ptr): addr = llmemory.cast_ptr_to_adr(func_ptr) - return ConstInt(heaptracker.adr2int(addr)) + return ConstInt(adr2int(addr)) MY_VTABLE = rclass.OBJECT_VTABLE # for tests only @@ -1897,7 +1898,7 @@ T_box = None else: vtable = vtable_for_T - T_box = ConstInt(heaptracker.adr2int(vtable_for_T_addr)) + T_box = ConstInt(adr2int(vtable_for_T_addr)) descr = cpu.sizeof(T, vtable) return t_box, T_box, descr @@ -1986,7 +1987,7 @@ def test_ooops_non_gc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') - v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + v = adr2int(llmemory.cast_ptr_to_adr(x)) r = self.execute_operation(rop.PTR_EQ, [InputArgInt(v), InputArgInt(v)], 'int') assert r == 1 r = self.execute_operation(rop.PTR_NE, [InputArgInt(v), InputArgInt(v)], 'int') @@ -2779,7 +2780,7 @@ cpu = self.cpu func_adr = llmemory.cast_ptr_to_adr(c_GetCurrentDir.funcsym) - funcbox = ConstInt(heaptracker.adr2int(func_adr)) + funcbox = ConstInt(adr2int(func_adr)) calldescr = cpu._calldescr_dynamic_for_tests( [types.ulong, types.pointer], types.ulong, @@ -3619,12 +3620,12 @@ rs = lltype.malloc(RS, immortal=True) rs.x = '?' x = cpu.bh_getfield_raw_i( - heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), + adr2int(llmemory.cast_ptr_to_adr(rs)), descrfld_rx) assert x == ord('?') # cpu.bh_setfield_raw_i( - heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), + adr2int(llmemory.cast_ptr_to_adr(rs)), ord('!'), descrfld_rx) assert rs.x == '!' # @@ -3699,7 +3700,7 @@ def test_guards_nongc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') - v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + v = adr2int(llmemory.cast_ptr_to_adr(x)) vbox = InputArgInt(v) ops = [ (rop.GUARD_NONNULL, vbox, False), @@ -3907,7 +3908,7 @@ a = lltype.malloc(ARRAY, 10, flavor='raw') a[7] = -4242 addr = llmemory.cast_ptr_to_adr(a) - abox = InputArgInt(heaptracker.adr2int(addr)) + abox = InputArgInt(adr2int(addr)) r1 = self.execute_operation(rop.GETARRAYITEM_RAW_I, [abox, InputArgInt(7)], 'int', descr=descr) assert r1 == -4242 @@ -3918,7 +3919,7 @@ descr = self.cpu.arraydescrof(ARRAY) a = lltype.malloc(ARRAY, 10, flavor='raw') addr = llmemory.cast_ptr_to_adr(a) - abox = InputArgInt(heaptracker.adr2int(addr)) + abox = InputArgInt(adr2int(addr)) self.execute_operation(rop.SETARRAYITEM_RAW, [abox, InputArgInt(5), InputArgInt(12345)], 'void', descr=descr) @@ -4192,7 +4193,7 @@ value = intmask(0xFFEEDDCCBBAA9988) expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) - a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) + a_rawint = adr2int(llmemory.cast_ptr_to_adr(a)) x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) @@ -4213,7 +4214,7 @@ value = intmask(0xFFEEDDCCBBAA9988) expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) - a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) + a_rawint = adr2int(llmemory.cast_ptr_to_adr(a)) res = self.execute_operation(rop.GETARRAYITEM_RAW_I, [InputArgInt(a_rawint), InputArgInt(3)], 'int', descr=descrarray) @@ -4547,7 +4548,7 @@ for test_case in test_cases: deadframe = self.cpu.execute_token(looptoken, test_case) got = self.cpu.get_int_value(deadframe, 0) - expected = heaptracker.int_signext(test_case, numbytes) + expected = int_signext(test_case, numbytes) assert got == expected def test_compile_asmlen(self): @@ -5069,7 +5070,7 @@ a[0] = rffi.cast(rffi.SHORT, 666) a[1] = rffi.cast(rffi.SHORT, 777) addr = llmemory.cast_ptr_to_adr(a) - a_int = heaptracker.adr2int(addr) + a_int = adr2int(addr) print 'a_int:', a_int self.execute_operation(rop.SETARRAYITEM_RAW, [ConstInt(a_int), ConstInt(0), ConstInt(-7654)], @@ -5104,7 +5105,7 @@ arraydescr = self.cpu.arraydescrof(A) a = lltype.malloc(A, 100) addr = llmemory.cast_ptr_to_adr(a) - a_int = heaptracker.adr2int(addr) + a_int = adr2int(addr) a_ref = lltype.cast_opaque_ptr(llmemory.GCREF, a) for (start, length) in [(0, 100), (49, 49), (1, 98), (15, 9), (10, 10), (47, 0), @@ -5259,7 +5260,7 @@ xptr = lltype.malloc(X) xptr.parent.typeptr = xtp x_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, xptr)) - X_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(xtp))) + X_box = ConstInt(adr2int(llmemory.cast_ptr_to_adr(xtp))) ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) ytp.subclassrange_min = 2 @@ -5270,7 +5271,7 @@ yptr = lltype.malloc(Y) yptr.parent.parent.typeptr = ytp y_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, yptr)) - Y_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(ytp))) + Y_box = ConstInt(adr2int(llmemory.cast_ptr_to_adr(ytp))) ztp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) ztp.subclassrange_min = 4 @@ -5282,7 +5283,7 @@ zptr = lltype.malloc(Z) zptr.parent.typeptr = ztp z_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, zptr)) - Z_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(ztp))) + Z_box = ConstInt(adr2int(llmemory.cast_ptr_to_adr(ztp))) for num, arg, klass, is_subclass in [ (1, x_box, X_box, True), diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py --- a/rpython/jit/backend/test/test_ll_random.py +++ b/rpython/jit/backend/test/test_ll_random.py @@ -5,6 +5,7 @@ from rpython.jit.backend.test.test_random import getint, getref_base, getref from rpython.jit.metainterp.resoperation import ResOperation, rop, optypes from rpython.jit.metainterp.history import ConstInt, ConstPtr, getkind +from rpython.jit.metainterp.support import adr2int from rpython.jit.codewriter import heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rtyper.annlowlevel import llhelper @@ -219,7 +220,7 @@ # ____________________________________________________________ def ConstAddr(addr): - return ConstInt(heaptracker.adr2int(addr)) + return ConstInt(adr2int(addr)) class GuardClassOperation(test_random.GuardOperation): def gen_guard(self, builder, r): diff --git a/rpython/jit/codewriter/assembler.py b/rpython/jit/codewriter/assembler.py --- a/rpython/jit/codewriter/assembler.py +++ b/rpython/jit/codewriter/assembler.py @@ -1,9 +1,10 @@ from rpython.jit.metainterp.history import AbstractDescr, getkind +from rpython.jit.metainterp.support import adr2int, int2adr from rpython.jit.codewriter.flatten import Register, Label, TLabel, KINDS from rpython.jit.codewriter.flatten import ListOfKind, IndirectCallTargets from rpython.jit.codewriter.format import format_assembler from rpython.jit.codewriter.jitcode import SwitchDictDescr, JitCode -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.rlib.objectmodel import ComputedIntSymbolic from rpython.rlib.rarithmetic import r_int from rpython.flowspace.model import Constant @@ -77,7 +78,7 @@ value = llmemory.cast_ptr_to_adr(value) TYPE = llmemory.Address if TYPE == llmemory.Address: - value = heaptracker.adr2int(value) + value = adr2int(value) if TYPE is lltype.SingleFloat: value = longlong.singlefloat2int(value) if not isinstance(value, (llmemory.AddressAsInt, @@ -265,7 +266,7 @@ # Helper called at the end of assembling. Registers the extra # functions shown in _callinfo_for_oopspec. for func in callinfocollection.all_function_addresses_as_int(): - func = heaptracker.int2adr(func) + func = int2adr(func) self.see_raw_object(func.ptr) diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py --- a/rpython/jit/codewriter/effectinfo.py +++ b/rpython/jit/codewriter/effectinfo.py @@ -3,6 +3,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.translator.backendopt.graphanalyze import BoolGraphAnalyzer from rpython.tool.algo import bitstring +from rpython.jit.metainterp.support import int2adr class UnsupportedFieldExc(Exception): @@ -445,9 +446,8 @@ return (None, 0) def _funcptr_for_oopspec_memo(self, oopspecindex): - from rpython.jit.codewriter import heaptracker _, func_as_int = self.callinfo_for_oopspec(oopspecindex) - funcadr = heaptracker.int2adr(func_as_int) + funcadr = int2adr(func_as_int) return funcadr.ptr _funcptr_for_oopspec_memo._annspecialcase_ = 'specialize:memo' diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py --- a/rpython/jit/codewriter/heaptracker.py +++ b/rpython/jit/codewriter/heaptracker.py @@ -1,30 +1,9 @@ -from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper import rclass -from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.rarithmetic import r_uint, intmask - - -def adr2int(addr): - # Cast an address to an int. Returns an AddressAsInt object which - # can be cast back to an address. - return llmemory.cast_adr_to_int(addr, "symbolic") - -def int2adr(int): - return llmemory.cast_int_to_adr(int) - -def int_signext(value, numbytes): - b8 = numbytes * 8 - a = r_uint(value) - a += r_uint(1 << (b8 - 1)) # a += 128 - a &= r_uint((1 << b8) - 1) # a &= 255 - a -= r_uint(1 << (b8 - 1)) # a -= 128 - return intmask(a) def is_immutable_struct(S): return isinstance(S, lltype.GcStruct) and S._hints.get('immutable', False) -# ____________________________________________________________ - def has_gcstruct_a_vtable(GCSTRUCT): if not isinstance(GCSTRUCT, lltype.GcStruct): return False @@ -132,4 +111,3 @@ return cur_index cur_index += 1 return -cur_index - 1 # not found - diff --git a/rpython/jit/codewriter/jitcode.py b/rpython/jit/codewriter/jitcode.py --- a/rpython/jit/codewriter/jitcode.py +++ b/rpython/jit/codewriter/jitcode.py @@ -1,5 +1,5 @@ from rpython.jit.metainterp.history import AbstractDescr, ConstInt -from rpython.jit.codewriter import heaptracker +from rpython.jit.metainterp.support import adr2int from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import base_int @@ -8,7 +8,7 @@ _empty_i = [] _empty_r = [] _empty_f = [] - + def __init__(self, name, fnaddr=None, calldescr=None, called_from=None): self.name = name self.fnaddr = fnaddr @@ -41,7 +41,7 @@ self._resulttypes = resulttypes # debugging def get_fnaddr_as_int(self): - return heaptracker.adr2int(self.fnaddr) + return adr2int(self.fnaddr) def num_regs_i(self): return ord(self.c_num_regs_i) diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -7,6 +7,7 @@ from rpython.jit.metainterp import quasiimmut from rpython.jit.metainterp.history import getkind from rpython.jit.metainterp.blackhole import BlackholeInterpreter +from rpython.jit.metainterp.support import adr2int from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.rlib import objectmodel from rpython.rlib.jit import _we_are_jitted @@ -1954,7 +1955,7 @@ if isinstance(op.args[0].value, str): pass # for tests only else: - func = heaptracker.adr2int( + func = adr2int( llmemory.cast_ptr_to_adr(op.args[0].value)) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) @@ -1982,7 +1983,7 @@ if isinstance(c_func.value, str): # in tests only func = c_func.value else: - func = heaptracker.adr2int( + func = adr2int( llmemory.cast_ptr_to_adr(c_func.value)) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) diff --git a/rpython/jit/codewriter/test/test_assembler.py b/rpython/jit/codewriter/test/test_assembler.py --- a/rpython/jit/codewriter/test/test_assembler.py +++ b/rpython/jit/codewriter/test/test_assembler.py @@ -3,8 +3,9 @@ from rpython.jit.codewriter.flatten import SSARepr, Label, TLabel, Register from rpython.jit.codewriter.flatten import ListOfKind, IndirectCallTargets from rpython.jit.codewriter.jitcode import MissingLiveness -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.metainterp.history import AbstractDescr +from rpython.jit.metainterp.support import adr2int from rpython.flowspace.model import Constant from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rlib.rarithmetic import r_int, r_uint @@ -106,7 +107,7 @@ assert assembler.insns == {'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2} - f_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(f)) + f_int = adr2int(llmemory.cast_ptr_to_adr(f)) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert jitcode.constants_r == [s_gcref] diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py --- a/rpython/jit/codewriter/test/test_flatten.py +++ b/rpython/jit/codewriter/test/test_flatten.py @@ -1,12 +1,12 @@ import py, sys from rpython.jit.codewriter import support -from rpython.jit.codewriter.heaptracker import int_signext from rpython.jit.codewriter.flatten import flatten_graph, reorder_renaming_list from rpython.jit.codewriter.flatten import GraphFlattener, ListOfKind, Register from rpython.jit.codewriter.format import assert_format from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.history import AbstractDescr +from rpython.jit.metainterp.support import int_signext from rpython.rtyper.lltypesystem import lltype, rstr, rffi from rpython.rtyper import rclass from rpython.flowspace.model import SpaceOperation, Variable, Constant diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -12,6 +12,7 @@ from rpython.jit.codewriter import heaptracker, effectinfo from rpython.jit.codewriter.flatten import ListOfKind from rpython.jit.codewriter.jtransform import Transformer, UnsupportedMallocFlags +from rpython.jit.metainterp.support import int2adr from rpython.jit.metainterp.history import getkind def const(x): @@ -1198,7 +1199,7 @@ got = cc.callinfocollection.seen[0] assert got[0] == effectinfo.EffectInfo.OS_UNI_CONCAT assert got[1] == op1.args[2] # the calldescr - assert heaptracker.int2adr(got[2]) == llmemory.cast_ptr_to_adr(func) + assert int2adr(got[2]) == llmemory.cast_ptr_to_adr(func) def test_str_slice(): # test that the oopspec is present and correctly transformed diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -1,9 +1,10 @@ -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.codewriter.jitcode import JitCode, SwitchDictDescr from rpython.jit.metainterp.compile import ResumeAtPositionDescr from rpython.jit.metainterp.jitexc import get_llexception, reraise from rpython.jit.metainterp import jitexc from rpython.jit.metainterp.history import MissingValue +from rpython.jit.metainterp.support import adr2int, int2adr, int_signext from rpython.rlib import longlong2float from rpython.rlib.debug import ll_assert, make_sure_not_resized from rpython.rlib.debug import check_annotation @@ -539,7 +540,7 @@ return i @arguments("i", "i", returns="i") def bhimpl_int_signext(a, b): - return heaptracker.int_signext(a, b) + return int_signext(a, b) @arguments("i", "i", returns="i") def bhimpl_uint_lt(a, b): @@ -930,7 +931,7 @@ @arguments("self", "i", "L", "pc", returns="L") def bhimpl_goto_if_exception_mismatch(self, vtable, target, pc): - adr = heaptracker.int2adr(vtable) + adr = int2adr(vtable) bounding_class = llmemory.cast_adr_to_ptr(adr, rclass.CLASSTYPE) real_instance = self.exception_last_value assert real_instance @@ -944,7 +945,7 @@ real_instance = self.exception_last_value assert real_instance adr = llmemory.cast_ptr_to_adr(real_instance.typeptr) - return heaptracker.adr2int(adr) + return adr2int(adr) @arguments("self", returns="r") def bhimpl_last_exc_value(self): @@ -1050,7 +1051,7 @@ def get_portal_runner(self, jdindex): jitdriver_sd = self.builder.metainterp_sd.jitdrivers_sd[jdindex] - fnptr = heaptracker.adr2int(jitdriver_sd.portal_runner_adr) + fnptr = adr2int(jitdriver_sd.portal_runner_adr) calldescr = jitdriver_sd.mainjitcode.calldescr return fnptr, calldescr @@ -1233,45 +1234,45 @@ @arguments("cpu", "j", "R", returns="i") def bhimpl_inline_call_r_i(cpu, jitcode, args_r): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_i(adr2int(jitcode.fnaddr), None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "R", returns="r") def bhimpl_inline_call_r_r(cpu, jitcode, args_r): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_r(adr2int(jitcode.fnaddr), None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "R") def bhimpl_inline_call_r_v(cpu, jitcode, args_r): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_v(adr2int(jitcode.fnaddr), None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", returns="i") def bhimpl_inline_call_ir_i(cpu, jitcode, args_i, args_r): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_i(adr2int(jitcode.fnaddr), args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", returns="r") def bhimpl_inline_call_ir_r(cpu, jitcode, args_i, args_r): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_r(adr2int(jitcode.fnaddr), args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R") def bhimpl_inline_call_ir_v(cpu, jitcode, args_i, args_r): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_v(adr2int(jitcode.fnaddr), args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="i") def bhimpl_inline_call_irf_i(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_i(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="r") def bhimpl_inline_call_irf_r(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_r(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="f") def bhimpl_inline_call_irf_f(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_f(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_f(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F") def bhimpl_inline_call_irf_v(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_v(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "i", "d", returns="r") diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -21,7 +21,8 @@ from rpython.jit.metainterp.resume import (PENDINGFIELDSP, ResumeDataDirectReader, AccumInfo) from rpython.jit.metainterp.resumecode import NUMBERING -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.metainterp.support import adr2int +from rpython.jit.codewriter import longlong def giveup(): @@ -1147,7 +1148,7 @@ raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr - funcbox = history.ConstInt(heaptracker.adr2int(k)) + funcbox = history.ConstInt(adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # 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 @@ -14,7 +14,8 @@ from rpython.jit.metainterp.resoperation import ResOperation, rop,\ AbstractValue, oparity, AbstractResOp, IntOp, RefOp, FloatOp,\ opclasses -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.metainterp.support import adr2int, int2adr +from rpython.jit.codewriter import longlong import weakref from rpython.jit.metainterp import jitexc @@ -181,7 +182,7 @@ kind = getkind(T) if kind == "int": if isinstance(T, lltype.Ptr): - intval = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + intval = adr2int(llmemory.cast_ptr_to_adr(x)) else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) @@ -228,7 +229,7 @@ getvalue = getint def getaddr(self): - return heaptracker.int2adr(self.value) + return int2adr(self.value) def _get_hash_(self): return make_hashable_int(self.value) @@ -351,7 +352,7 @@ from rpython.rtyper.lltypesystem.ll2ctypes import NotCtypesAllocatedStructure if not we_are_translated() and isinstance(i, llmemory.AddressAsInt): # Warning: such a hash changes at the time of translation - adr = heaptracker.int2adr(i) + adr = int2adr(i) try: return llmemory.cast_adr_to_int(adr, "emulated") except NotCtypesAllocatedStructure: diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py --- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py @@ -11,6 +11,7 @@ JitCellToken, TargetToken) from rpython.jit.metainterp.resoperation import rop, ResOperation,\ InputArgRef, InputArgInt +from rpython.jit.metainterp.support import adr2int from rpython.jit.metainterp.optimizeopt.shortpreamble import \ ShortPreambleBuilder, PreambleOp, ShortInputArg from rpython.jit.metainterp.compile import LoopCompileData @@ -18,7 +19,6 @@ NotVirtualStateInfo, LEVEL_CONSTANT, LEVEL_UNKNOWN, LEVEL_KNOWNCLASS,\ VirtualStateInfo from rpython.jit.metainterp.optimizeopt import info, optimizer -from rpython.jit.codewriter import heaptracker from rpython.jit.tool import oparser class FakeOptimizer(object): @@ -36,10 +36,10 @@ def get_box_replacement(self, box): return box - + class BaseTestUnroll(BaseTest, LLtypeMixin): enable_opts = "intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll" - + def optimize(self, ops): loop = self.parse(ops) self.add_guard_future_condition(loop) @@ -72,7 +72,7 @@ def producable_short_boxes(l): return [x for x in l if not isinstance(x.short_op, ShortInputArg)] - + class TestUnroll(BaseTestUnroll): def test_simple(self): loop = """ @@ -133,7 +133,7 @@ """ es, loop, preamble = self.optimize(loop) p0 = preamble.inputargs[0] - expected_class = heaptracker.adr2int(self.node_vtable_adr) + expected_class = adr2int(self.node_vtable_adr) assert expected_class == es.exported_infos[p0]._known_class.getint() vs = es.virtual_state assert vs.state[0].level == LEVEL_KNOWNCLASS @@ -160,7 +160,7 @@ p.set_forwarded(ptrinfo) vs.make_inputargs([p, p, i], FakeOptimizer()) - def test_short_boxes_heapcache(self): + def test_short_boxes_heapcache(self): loop = """ [p0, i1] i0 = getfield_gc_i(p0, descr=valuedescr) @@ -230,7 +230,7 @@ assert len(es.short_boxes) == 4 # both getfields are available as # well as getfield_gc - + def test_p123_anti_nested(self): loop = """ [i1, p2, p3] diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2,7 +2,7 @@ import py -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.codewriter.jitcode import JitCode, SwitchDictDescr from rpython.jit.metainterp import history, compile, resume, executor, jitexc @@ -13,6 +13,7 @@ from rpython.jit.metainterp.logger import Logger from rpython.jit.metainterp.optimizeopt.util import args_dict from rpython.jit.metainterp.resoperation import rop, OpHelpers, GuardResOp +from rpython.jit.metainterp.support import adr2int from rpython.rlib.rjitlog import rjitlog as jl from rpython.rlib import nonconst, rstack from rpython.rlib.debug import debug_start, debug_stop, debug_print @@ -1161,7 +1162,7 @@ assembler_call=False): portal_code = targetjitdriver_sd.mainjitcode k = targetjitdriver_sd.portal_runner_adr - funcbox = ConstInt(heaptracker.adr2int(k)) + funcbox = ConstInt(adr2int(k)) return self.do_residual_call(funcbox, allboxes, portal_code.calldescr, pc, assembler_call=assembler_call, assembler_call_jd=targetjitdriver_sd) @@ -2675,7 +2676,7 @@ exception_obj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, exception) if exception_obj: - exc_class = heaptracker.adr2int( + exc_class = adr2int( llmemory.cast_ptr_to_adr(exception_obj.typeptr)) else: exc_class = 0 @@ -2974,7 +2975,7 @@ def handle_possible_exception(self): if self.last_exc_value: - exception_box = ConstInt(heaptracker.adr2int( + exception_box = ConstInt(adr2int( llmemory.cast_ptr_to_adr(self.last_exc_value.typeptr))) op = self.generate_guard(rop.GUARD_EXCEPTION, None, [exception_box]) @@ -3269,7 +3270,7 @@ calldescr._original_func_ = argboxes[0].getint() effectinfo = calldescr.get_extra_info() realfuncaddr, saveerr = effectinfo.call_release_gil_target - funcbox = ConstInt(heaptracker.adr2int(realfuncaddr)) + funcbox = ConstInt(adr2int(realfuncaddr)) savebox = ConstInt(saveerr) opnum = rop.call_release_gil_for_descr(calldescr) return self.history.record_nospec(opnum, diff --git a/rpython/jit/metainterp/support.py b/rpython/jit/metainterp/support.py new file mode 100644 --- /dev/null +++ b/rpython/jit/metainterp/support.py @@ -0,0 +1,26 @@ +from rpython.rtyper.lltypesystem import llmemory +from rpython.rlib.rarithmetic import r_uint, intmask + +def adr2int(addr): + """ + Cast an address to an int. + + Returns an AddressAsInt object which can be cast back to an address. + """ + return llmemory.cast_adr_to_int(addr, "symbolic") + +def int2adr(int): + """ + Cast an int back to an address. + + Inverse of adr2int(). + """ + return llmemory.cast_int_to_adr(int) + +def int_signext(value, numbytes): + b8 = numbytes * 8 + a = r_uint(value) + a += r_uint(1 << (b8 - 1)) # a += 128 + a &= r_uint((1 << b8) - 1) # a &= 255 + a -= r_uint(1 << (b8 - 1)) # a -= 128 + return intmask(a) diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py --- a/rpython/jit/metainterp/test/test_resume.py +++ b/rpython/jit/metainterp/test/test_resume.py @@ -19,9 +19,10 @@ from rpython.jit.metainterp.history import ( ConstInt, Const, AbstractDescr, ConstPtr, ConstFloat, IntFrontendOp, RefFrontendOp, CONST_NULL) +from rpython.jit.metainterp.support import adr2int from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin from rpython.jit.metainterp import executor -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib.debug import debug_start, debug_stop, debug_print,\ have_debug_prints @@ -639,7 +640,7 @@ fakeoptimizer = FakeOptimizer_VirtualValue() def ConstAddr(addr): # compatibility - return ConstInt(heaptracker.adr2int(addr)) + return ConstInt(adr2int(addr)) def virtual_value(keybox, value, next): vv = VirtualValue( diff --git a/rpython/jit/metainterp/test/test_support.py b/rpython/jit/metainterp/test/test_support.py new file mode 100644 --- /dev/null +++ b/rpython/jit/metainterp/test/test_support.py @@ -0,0 +1,14 @@ +from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.jit.metainterp.support import adr2int, int2adr + +def test_cast_adr_to_int_and_back(): + X = lltype.Struct('X', ('foo', lltype.Signed)) + x = lltype.malloc(X, immortal=True) + x.foo = 42 + a = llmemory.cast_ptr_to_adr(x) + i = adr2int(a) + assert lltype.typeOf(i) is lltype.Signed + a2 = int2adr(i) + assert llmemory.cast_adr_to_ptr(a2, lltype.Ptr(X)) == x + assert adr2int(llmemory.NULL) == 0 + assert int2adr(0) == llmemory.NULL diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -1,7 +1,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.jit.metainterp import history -from rpython.jit.codewriter import heaptracker +from rpython.jit.metainterp.support import adr2int from rpython.rlib.objectmodel import r_dict @@ -17,6 +17,6 @@ def cls_of_box(self, box): obj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, box.getref_base()) cls = llmemory.cast_ptr_to_adr(obj.typeptr) - return history.ConstInt(heaptracker.adr2int(cls)) + return history.ConstInt(adr2int(cls)) llhelper = LLTypeHelper() diff --git a/rpython/jit/metainterp/virtualref.py b/rpython/jit/metainterp/virtualref.py --- a/rpython/jit/metainterp/virtualref.py +++ b/rpython/jit/metainterp/virtualref.py @@ -2,8 +2,9 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.jit.metainterp import history -from rpython.jit.metainterp.virtualizable import TOKEN_NONE -from rpython.jit.metainterp.virtualizable import TOKEN_TRACING_RESCALL +from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.virtualizable import ( + TOKEN_NONE, TOKEN_TRACING_RESCALL) from rpython.jit.codewriter import heaptracker from rpython.rlib.jit import InvalidVirtualRef @@ -34,7 +35,7 @@ 'jit_virtual_ref') # build some constants adr = llmemory.cast_ptr_to_adr(self.jit_virtual_ref_vtable) - adr = heaptracker.adr2int(adr) + adr = adr2int(adr) self.jit_virtual_ref_const_class = history.ConstInt(adr) fielddescrof = self.cpu.fielddescrof self.descr_virtual_token = fielddescrof(self.JIT_VIRTUAL_REF, diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py --- a/rpython/jit/metainterp/warmstate.py +++ b/rpython/jit/metainterp/warmstate.py @@ -1,8 +1,9 @@ import sys import weakref -from rpython.jit.codewriter import support, heaptracker, longlong +from rpython.jit.codewriter import support, longlong from rpython.jit.metainterp import resoperation, history, jitexc +from rpython.jit.metainterp.support import adr2int, int2adr from rpython.rlib.debug import debug_start, debug_stop, debug_print from rpython.rlib.debug import have_debug_prints_for from rpython.rlib.jit import PARAMETERS @@ -48,7 +49,7 @@ return lltype.cast_opaque_ptr(llmemory.GCREF, value) else: adr = llmemory.cast_ptr_to_adr(value) - return heaptracker.adr2int(adr) + return adr2int(adr) elif isinstance(value, float): return longlong.getfloatstorage(value) else: @@ -62,7 +63,7 @@ if TYPE.TO._gckind == "gc": return box.getref(TYPE) else: - adr = heaptracker.int2adr(box.getint()) + adr = int2adr(box.getint()) return llmemory.cast_adr_to_ptr(adr, TYPE) if TYPE == lltype.Float: return box.getfloat() @@ -82,7 +83,7 @@ return res else: adr = llmemory.cast_ptr_to_adr(value) - value = heaptracker.adr2int(adr) + value = adr2int(adr) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): @@ -150,7 +151,7 @@ app-level Python code. We create subclasses of BaseJitCell --one per jitdriver-- so that - they can store greenkeys of different types. + they can store greenkeys of different types. Note that we don't create a JitCell the first time we see a given greenkey position in the interpreter. At first, we only hash the @@ -384,7 +385,7 @@ if vinfo is not None: virtualizable = args[index_of_virtualizable] vinfo.clear_vable_token(virtualizable) - + deadframe = func_execute_token(loop_token, *args) # # Record in the memmgr that we just ran this loop, @@ -698,7 +699,7 @@ drivername = jitdriver.name else: drivername = '' - # get_location returns + # get_location returns get_location_ptr = getattr(self.jitdriver_sd, '_get_location_ptr', None) if get_location_ptr is not None: types = self.jitdriver_sd._get_loc_types diff --git a/rpython/jit/tool/oparser_model.py b/rpython/jit/tool/oparser_model.py --- a/rpython/jit/tool/oparser_model.py +++ b/rpython/jit/tool/oparser_model.py @@ -1,3 +1,5 @@ +from rpython.jit.metainterp.support import adr2int + class Boxes(object): pass @@ -21,7 +23,6 @@ @staticmethod def ptr_to_int(obj): - from rpython.jit.codewriter.heaptracker import adr2int from rpython.rtyper.lltypesystem import llmemory return adr2int(llmemory.cast_ptr_to_adr(obj)) From pypy.commits at gmail.com Fri Apr 5 05:28:38 2019 From: pypy.commits at gmail.com (fijal) Date: Fri, 05 Apr 2019 02:28:38 -0700 (PDT) Subject: [pypy-commit] pypy arm64: use only first 16 registers and make sure the jitframe_fixed_size agrees Message-ID: <5ca71fc6.1c69fb81.c21d9.9f32@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96417:230e2b6a0bae Date: 2019-04-05 09:27 +0000 http://bitbucket.org/pypy/pypy/changeset/230e2b6a0bae/ Log: use only first 16 registers and make sure the jitframe_fixed_size agrees diff --git a/rpython/jit/backend/aarch64/arch.py b/rpython/jit/backend/aarch64/arch.py --- a/rpython/jit/backend/aarch64/arch.py +++ b/rpython/jit/backend/aarch64/arch.py @@ -8,5 +8,5 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 12 + 8 -# 12 GPR + 8 VFP Regs +JITFRAME_FIXED_SIZE = 16 + 16 +# 20 GPR + 16 VFP Regs diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1,7 +1,7 @@ from rpython.jit.backend.aarch64.arch import WORD, JITFRAME_FIXED_SIZE from rpython.jit.backend.aarch64.codebuilder import InstrBuilder -#from rpython.jit.backend.arm.locations import imm, StackLocation, get_fp_offset +from rpython.jit.backend.arm.locations import imm, StackLocation, get_fp_offset #from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size from rpython.jit.backend.aarch64.opassembler import ResOpAssembler from rpython.jit.backend.aarch64.regalloc import (Regalloc, @@ -556,6 +556,10 @@ else: XXX + def new_stack_loc(self, i, tp): + base_ofs = self.cpu.get_baseofs_of_frame_field() + return StackLocation(i, get_fp_offset(base_ofs, i), tp) + def regalloc_mov(self, prev_loc, loc): """Moves a value from a previous location to some other location""" if prev_loc.is_imm(): diff --git a/rpython/jit/backend/aarch64/registers.py b/rpython/jit/backend/aarch64/registers.py --- a/rpython/jit/backend/aarch64/registers.py +++ b/rpython/jit/backend/aarch64/registers.py @@ -11,7 +11,7 @@ vfpregisters = [VFPRegisterLocation(i) for i in range(32)] all_vfp_regs = vfpregisters[:16] -all_regs = registers[:16] + [x19, x20, x21, x22] +all_regs = registers[:16] #+ [x19, x20, x21, x22] lr = x30 fp = x29 diff --git a/rpython/jit/backend/aarch64/runner.py b/rpython/jit/backend/aarch64/runner.py --- a/rpython/jit/backend/aarch64/runner.py +++ b/rpython/jit/backend/aarch64/runner.py @@ -13,6 +13,7 @@ gen_regs = r.all_regs float_regs = VFPRegisterManager.all_regs + from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE IS_64_BIT = True From pypy.commits at gmail.com Fri Apr 5 05:29:57 2019 From: pypy.commits at gmail.com (fijal) Date: Fri, 05 Apr 2019 02:29:57 -0700 (PDT) Subject: [pypy-commit] pypy arm64: bring it more to reality Message-ID: <5ca72015.1c69fb81.55b22.f3fb@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96418:0b7c212b0618 Date: 2019-04-05 09:29 +0000 http://bitbucket.org/pypy/pypy/changeset/0b7c212b0618/ Log: bring it more to reality diff --git a/rpython/jit/backend/aarch64/arch.py b/rpython/jit/backend/aarch64/arch.py --- a/rpython/jit/backend/aarch64/arch.py +++ b/rpython/jit/backend/aarch64/arch.py @@ -9,4 +9,4 @@ # Stack frame fixed area # Currently only the force_index JITFRAME_FIXED_SIZE = 16 + 16 -# 20 GPR + 16 VFP Regs +# 16 GPR + 16 VFP Regs # 20 if we want to use 4 extra x19..x22 diff --git a/rpython/jit/backend/aarch64/registers.py b/rpython/jit/backend/aarch64/registers.py --- a/rpython/jit/backend/aarch64/registers.py +++ b/rpython/jit/backend/aarch64/registers.py @@ -21,6 +21,6 @@ ip1 = x17 ip0 = x16 -callee_saved_registers = [x19, x20, x21, x22] +callee_saved_registers = [] # x19, x20, x21, x22] argument_regs = caller_resp = [x0, x1, x2, x3, x4, x5, x6, x7] From pypy.commits at gmail.com Fri Apr 5 07:07:44 2019 From: pypy.commits at gmail.com (fijal) Date: Fri, 05 Apr 2019 04:07:44 -0700 (PDT) Subject: [pypy-commit] pypy arm64: a bit of progresss. now the same test fails, but for better reasons Message-ID: <5ca73700.1c69fb81.dab9e.0633@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96419:4f3f6fe5df0a Date: 2019-04-05 11:07 +0000 http://bitbucket.org/pypy/pypy/changeset/4f3f6fe5df0a/ Log: a bit of progresss. now the same test fails, but for better reasons diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1,6 +1,6 @@ from rpython.jit.backend.aarch64.arch import WORD, JITFRAME_FIXED_SIZE -from rpython.jit.backend.aarch64.codebuilder import InstrBuilder +from rpython.jit.backend.aarch64.codebuilder import InstrBuilder, OverwritingBuilder from rpython.jit.backend.arm.locations import imm, StackLocation, get_fp_offset #from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size from rpython.jit.backend.aarch64.opassembler import ResOpAssembler @@ -253,6 +253,36 @@ mc.ADD_ri(r.ip.value, r.fp.value, imm=ofs+base_ofs) mc.VSTM(r.ip.value, [vfpr.value for vfpr in regs]) + def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Pop general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX add special case if ignored_regs are a block at the start of regs + if not ignored_regs: # we want to pop a contiguous block of regs + assert base_ofs < 0x100 + for i, reg in enumerate(regs): + mc.LDR_ri(reg.value, r.fp.value, base_ofs + i * WORD) + else: + for reg in ignored_regs: + assert not reg.is_vfp_reg() # sanity check + # we can have holes in the list of regs + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + ofs = i * WORD + base_ofs + self.load_reg(mc, gpr, r.fp, ofs) + if withfloats: + # Pop VFP regs + regs = VFPRegisterManager.all_regs + ofs = len(CoreRegisterManager.all_regs) * WORD + assert check_imm_arg(ofs+base_ofs) + mc.ADD_ri(r.ip.value, r.fp.value, imm=ofs+base_ofs) + mc.VLDM(r.ip.value, [vfpr.value for vfpr in regs]) + def _build_failure_recovery(self, exc, withfloats=False): mc = InstrBuilder() self._push_all_regs_to_jitframe(mc, [], withfloats) @@ -289,6 +319,75 @@ pass # XXX def build_frame_realloc_slowpath(self): + # this code should do the following steps + # a) store all registers in the jitframe + # b) fish for the arguments passed by the caller + # c) store the gcmap in the jitframe + # d) call realloc_frame + # e) set the fp to point to the new jitframe + # f) store the address of the new jitframe in the shadowstack + # c) set the gcmap field to 0 in the new jitframe + # g) restore registers and return + mc = InstrBuilder() + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) + # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame + # and the expected_size pushed in _check_stack_frame + # pop the values passed on the stack, gcmap -> r0, expected_size -> r1 + mc.LDP_rri(r.x0.value, r.x1.value, r.sp.value, 0) + + # XXX # store return address and keep the stack aligned + # mc.PUSH([r.ip.value, r.lr.value]) + + # store the current gcmap(r0) in the jitframe + gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.STR_ri(r.x0.value, r.fp.value, gcmap_ofs) + + # set first arg, which is the old jitframe address + mc.MOV_rr(r.x0.value, r.fp.value) + + # store a possibly present exception + # we use a callee saved reg here as a tmp for the exc. + self._store_and_reset_exception(mc, None, r.x19, on_frame=True) + + # call realloc_frame, it takes two arguments + # arg0: the old jitframe + # arg1: the new size + # + mc.BL(self.cpu.realloc_frame) + + # set fp to the new jitframe returned from the previous call + mc.MOV_rr(r.fp.value, r.x0.value) + + # restore a possibly present exception + self._restore_exception(mc, None, r.x19) + + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self._load_shadowstack_top(mc, r.r5, gcrootmap) + # store the new jitframe addr in the shadowstack + mc.STR_ri(r.r0.value, r.r5.value, imm=-WORD) + + # reset the jf_gcmap field in the jitframe + mc.gen_load_int(r.ip0.value, 0) + mc.STR_ri(r.ip0.value, r.fp.value, gcmap_ofs) + + # restore registers + self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) + + # return + mc.ADD_ri(r.sp.value, r.sp.value, 2*WORD) + mc.LDR_ri(r.lr.value, r.sp.value, WORD) + mc.RET_r(r.lr.value) + self._frame_realloc_slowpath = mc.materialize(self.cpu, []) + + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + on_frame=False): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ + pass + + def _restore_exception(self, mc, excvalloc, exctploc): pass def _build_propagate_exception_path(self): @@ -303,8 +402,41 @@ def _check_frame_depth_debug(self, mc): pass - def _check_frame_depth(self, mc, gcmap): - pass # XXX + def _check_frame_depth(self, mc, gcmap, expected_size=-1): + """ check if the frame is of enough depth to follow this bridge. + Otherwise reallocate the frame in a helper. + There are other potential solutions + to that, but this one does not sound too bad. + """ + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + mc.LDR_ri(r.ip0.value, r.fp.value, ofs) + stack_check_cmp_ofs = mc.currpos() + if expected_size == -1: + for _ in range(mc.get_max_size_of_gen_load_int()): + mc.NOP() + else: + mc.gen_load_int(r.lr.value, expected_size) + mc.CMP_rr(r.ip0.value, r.lr.value) + + jg_location = mc.currpos() + mc.BRK() + + # the size value is still stored in lr + mc.SUB_ri(r.sp.value, r.sp.value, 2*WORD) + mc.STR_ri(r.lr.value, r.sp.value, WORD) + + mc.gen_load_int(r.ip0.value, rffi.cast(lltype.Signed, gcmap)) + mc.STR_ri(r.ip0.value, r.sp.value, 0) + + mc.BL(self._frame_realloc_slowpath) + + # patch jg_location above + currpos = mc.currpos() + pmc = OverwritingBuilder(mc, jg_location, WORD) + pmc.B_ofs_cond(currpos - jg_location, c.GE) + + self.frame_depth_to_patch.append(stack_check_cmp_ofs) def update_frame_depth(self, frame_depth): baseofs = self.cpu.get_baseofs_of_frame_field() @@ -351,7 +483,10 @@ self.teardown_gcrefs_list() def patch_stack_checks(self, framedepth, rawstart): - pass # XXX + for ofs in self.frame_depth_to_patch: + mc = InstrBuilder() + mc.gen_load_int(r.lr.value, framedepth) + mc.copy_to_raw_memory(ofs + rawstart) def load_from_gc_table(self, regnum, index): address_in_buffer = index * WORD # at the start of the buffer diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -119,6 +119,9 @@ assert 0 <= imm <= 4095 self.write32((base << 22) | (imm << 10) | (rn << 5) | 0b11111) + def NOP(self): + self.write32(0b11010101000000110010000000011111) + def B_ofs(self, ofs): base = 0b000101 assert ofs & 0x3 == 0 @@ -170,6 +173,26 @@ shift += 16 value >>= 16 + def get_max_size_of_gen_load_int(self): + return 4 + + +class OverwritingBuilder(AbstractAarch64Builder): + def __init__(self, cb, start, size): + AbstractAarch64Builder.__init__(self) + self.cb = cb + self.index = start + self.start = start + self.end = start + size + + def currpos(self): + return self.index + + def writechar(self, char): + assert self.index <= self.end + self.cb.overwrite(self.index, char) + self.index += 1 + class InstrBuilder(BlockBuilderMixin, AbstractAarch64Builder): diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -122,7 +122,7 @@ def emit_op_guard_false(self, op, arglocs): self.load_condition_into_cc(arglocs[1]) - self._emit_guard(op, c.NE, arglocs) + self._emit_guard(op, c.EQ, arglocs) def emit_op_label(self, op, arglocs): pass diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -122,6 +122,8 @@ base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): + import pdb + pdb.set_trace() try: if not we_are_translated(): assert not self._exception_emulator[0] diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -340,6 +340,9 @@ self.cpu.compile_bridge(faildescr1, [i0], bridge, looptoken) + deadframe = self.cpu.execute_token(looptoken, 0) + fail = self.cpu.get_latest_descr(deadframe) + assert fail.identifier == 2 deadframe = self.cpu.execute_token(looptoken, 1) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 3 From pypy.commits at gmail.com Fri Apr 5 07:53:41 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 05 Apr 2019 04:53:41 -0700 (PDT) Subject: [pypy-commit] pypy default: An attempt to find a general fix for arm/regalloc. In this backend (and not Message-ID: <5ca741c5.1c69fb81.6bb3b.480f@mx.google.com> Author: Armin Rigo Branch: Changeset: r96420:a243e4e0b21c Date: 2019-04-05 13:49 +0200 http://bitbucket.org/pypy/pypy/changeset/a243e4e0b21c/ Log: An attempt to find a general fix for arm/regalloc. In this backend (and not the others as far as I can tell), there can be a mixture of calls to make_sure_var_in_reg() and get_scratch_reg(). Try to make sure that none of these calls will accidentally return a register that a previous call already returned. diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -84,6 +84,8 @@ return [] class ARMRegisterManager(RegisterManager): + FORBID_TEMP_BOXES = True + def return_constant(self, v, forbidden_vars=[], selected_reg=None): self._check_type(v) if isinstance(v, Const): @@ -94,7 +96,7 @@ else: tp = INT loc = self.get_scratch_reg(tp, - self.temp_boxes + forbidden_vars, + forbidden_vars, selected_reg=selected_reg) immvalue = self.convert_to_imm(v) self.assembler.load(loc, immvalue) @@ -129,9 +131,9 @@ def get_scratch_reg(self, type=FLOAT, forbidden_vars=[], selected_reg=None): assert type == FLOAT # for now box = TempFloat() - self.temp_boxes.append(box) reg = self.force_allocate_reg(box, forbidden_vars=forbidden_vars, selected_reg=selected_reg) + self.temp_boxes.append(box) return reg @@ -164,9 +166,9 @@ box = TempInt() else: box = TempPtr() - self.temp_boxes.append(box) reg = self.force_allocate_reg(box, forbidden_vars=forbidden_vars, selected_reg=selected_reg) + self.temp_boxes.append(box) return reg def get_free_reg(self): diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -280,6 +280,7 @@ no_lower_byte_regs = [] save_around_call_regs = [] frame_reg = None + FORBID_TEMP_BOXES = False def __init__(self, longevity, frame_manager=None, assembler=None): self.free_regs = self.all_regs[:] @@ -441,6 +442,8 @@ reg = self.reg_bindings[next] if next in forbidden_vars: continue + if self.FORBID_TEMP_BOXES and next in self.temp_boxes: + continue if selected_reg is not None: if reg is selected_reg: return next From pypy.commits at gmail.com Fri Apr 5 13:14:22 2019 From: pypy.commits at gmail.com (rlamy) Date: Fri, 05 Apr 2019 10:14:22 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Create ptr2int() helper Message-ID: <5ca78cee.1c69fb81.345aa.d9f9@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96421:8e5f665823d9 Date: 2019-04-05 03:36 +0100 http://bitbucket.org/pypy/pypy/changeset/8e5f665823d9/ Log: Create ptr2int() helper diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -9,7 +9,7 @@ from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.optimizeopt import intbounds from rpython.jit.metainterp.optimize import SpeculativeError -from rpython.jit.metainterp.support import adr2int, int2adr, int_signext +from rpython.jit.metainterp.support import ptr2int, int_signext from rpython.jit.codewriter import longlong, heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo @@ -137,7 +137,7 @@ if self._vtable is Ellipsis: self._vtable = heaptracker.get_vtable_for_gcstruct(self._runner, self.S) - return adr2int(llmemory.cast_ptr_to_adr(self._vtable)) + return ptr2int(self._vtable) def is_immutable(self): return heaptracker.is_immutable_struct(self.S) @@ -877,8 +877,7 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return adr2int(result_adr) + return ptr2int(struct.typeptr) # vector operations vector_arith_code = """ @@ -1552,13 +1551,12 @@ return res def execute_restore_exception(self, descr, kls, e): - kls = int2adr(kls) if e: value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, e) - assert llmemory.cast_ptr_to_adr(value.typeptr) == kls + assert ptr2int(value.typeptr) == kls lle = LLException(value.typeptr, e) else: - assert kls == llmemory.NULL + assert kls == 0 lle = None self.last_exception = lle diff --git a/rpython/jit/backend/llgraph/support.py b/rpython/jit/backend/llgraph/support.py --- a/rpython/jit/backend/llgraph/support.py +++ b/rpython/jit/backend/llgraph/support.py @@ -1,6 +1,6 @@ from rpython.jit.codewriter import longlong -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import adr2int, ptr2int from rpython.jit.metainterp.history import getkind from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint @@ -19,7 +19,7 @@ def cast_to_int(x): TP = lltype.typeOf(x) if isinstance(TP, lltype.Ptr): - return adr2int(llmemory.cast_ptr_to_adr(x)) + return ptr2int(x) if TP == llmemory.Address: return adr2int(x) if TP is lltype.SingleFloat: diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py --- a/rpython/jit/backend/llsupport/descr.py +++ b/rpython/jit/backend/llsupport/descr.py @@ -4,7 +4,7 @@ from rpython.jit.backend.llsupport import symbolic, support from rpython.jit.metainterp.history import AbstractDescr, getkind, FLOAT, INT from rpython.jit.metainterp import history -from rpython.jit.metainterp.support import adr2int, int2adr +from rpython.jit.metainterp.support import ptr2int, int2adr from rpython.jit.codewriter import heaptracker, longlong from rpython.jit.codewriter.longlong import is_longlong from rpython.jit.metainterp.optimizeopt import intbounds @@ -96,7 +96,7 @@ return self.immutable_flag def get_vtable(self): - return adr2int(llmemory.cast_ptr_to_adr(self.vtable)) + return ptr2int(self.vtable) def get_type_id(self): assert self.tid diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -11,7 +11,7 @@ from rpython.jit.codewriter import heaptracker from rpython.jit.metainterp.history import ConstPtr, AbstractDescr, ConstInt from rpython.jit.metainterp.resoperation import rop, ResOperation -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr, FieldDescr @@ -67,7 +67,7 @@ @specialize.arg(1) def get_malloc_fn_addr(self, funcname): ll_func = self.get_malloc_fn(funcname) - return adr2int(llmemory.cast_ptr_to_adr(ll_func)) + return ptr2int(ll_func) def _freeze_(self): return True diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -8,7 +8,7 @@ from rpython.rlib.objectmodel import we_are_translated, specialize, compute_hash from rpython.jit.metainterp import history, compile from rpython.jit.metainterp.optimize import SpeculativeError -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import adr2int, ptr2int from rpython.jit.codewriter import longlong from rpython.jit.backend.model import AbstractCPU from rpython.jit.backend.llsupport import symbolic, jitframe @@ -159,7 +159,7 @@ graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() - self.realloc_frame = adr2int(llmemory.cast_ptr_to_adr(fptr)) + self.realloc_frame = ptr2int(fptr) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame_crash) @@ -171,7 +171,7 @@ graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() - self.realloc_frame_crash = adr2int(llmemory.cast_ptr_to_adr(fptr)) + self.realloc_frame_crash = ptr2int(fptr) def _setup_exception_handling_untranslated(self): # for running un-translated only, all exceptions occurring in the @@ -775,8 +775,7 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return adr2int(result_adr) + return ptr2int(struct.typeptr) def bh_new_array(self, length, arraydescr): return self.gc_ll_descr.gc_malloc_array(length, arraydescr) 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 @@ -6,7 +6,7 @@ from rpython.jit.metainterp.history import ( ConstInt, ConstPtr, JitCellToken, new_ref_dict) from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.jit.backend.llsupport.symbolic import (WORD, get_field_token, get_array_token) from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr @@ -606,11 +606,9 @@ descrs = self.gc_ll_descr.getframedescrs(self.cpu) loop_token = op.getdescr() assert isinstance(loop_token, JitCellToken) - jfi = loop_token.compiled_loop_token.frame_info - llfi = adr2int(llmemory.cast_ptr_to_adr(jfi)) + llfi = ptr2int(loop_token.compiled_loop_token.frame_info) frame = self.gen_malloc_frame(llfi) - self.emit_setfield(frame, ConstInt(llfi), - descr=descrs.jf_frame_info) + self.emit_setfield(frame, ConstInt(llfi), descr=descrs.jf_frame_info) arglist = op.getarglist() index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -2,7 +2,7 @@ from rpython.jit.metainterp.history import BasicFinalDescr,\ JitCellToken, ConstInt, ConstFloat from rpython.jit.metainterp.resoperation import rop, InputArgInt, InputArgFloat -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory @@ -50,8 +50,7 @@ @classmethod def get_funcbox(cls, cpu, func_ptr): - addr = llmemory.cast_ptr_to_adr(func_ptr) - return ConstInt(adr2int(addr)) + return ConstInt(ptr2int(func_ptr)) def test_call_aligned_with_spilled_values(self): cpu = self.cpu diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -11,7 +11,7 @@ from rpython.jit.metainterp.resoperation import ( ResOperation, rop, InputArgInt, InputArgFloat, InputArgRef) from rpython.jit.metainterp.executor import wrap_constant -from rpython.jit.metainterp.support import adr2int, int_signext +from rpython.jit.metainterp.support import ptr2int, int_signext from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi @@ -1846,8 +1846,7 @@ @classmethod def get_funcbox(cls, cpu, func_ptr): - addr = llmemory.cast_ptr_to_adr(func_ptr) - return ConstInt(adr2int(addr)) + return ConstInt(ptr2int(func_ptr)) MY_VTABLE = rclass.OBJECT_VTABLE # for tests only @@ -1869,7 +1868,6 @@ def alloc_instance(self, T): if hasattr(T, 'parent'): vtable_for_T = lltype.malloc(self.MY_VTABLE, immortal=True) - vtable_for_T_addr = llmemory.cast_ptr_to_adr(vtable_for_T) else: vtable_for_T = lltype.nullptr(rclass.OBJECT_VTABLE) cpu = self.cpu @@ -1898,7 +1896,7 @@ T_box = None else: vtable = vtable_for_T - T_box = ConstInt(adr2int(vtable_for_T_addr)) + T_box = ConstInt(ptr2int(vtable_for_T_addr)) descr = cpu.sizeof(T, vtable) return t_box, T_box, descr @@ -1987,7 +1985,7 @@ def test_ooops_non_gc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') - v = adr2int(llmemory.cast_ptr_to_adr(x)) + v = ptr2int(x) r = self.execute_operation(rop.PTR_EQ, [InputArgInt(v), InputArgInt(v)], 'int') assert r == 1 r = self.execute_operation(rop.PTR_NE, [InputArgInt(v), InputArgInt(v)], 'int') @@ -2779,8 +2777,7 @@ lltype.free(buffer, flavor='raw') cpu = self.cpu - func_adr = llmemory.cast_ptr_to_adr(c_GetCurrentDir.funcsym) - funcbox = ConstInt(adr2int(func_adr)) + funcbox = ConstInt(ptr2int(c_GetCurrentDir.funcsym)) calldescr = cpu._calldescr_dynamic_for_tests( [types.ulong, types.pointer], types.ulong, @@ -3619,14 +3616,10 @@ descrfld_rx = cpu.fielddescrof(RS, 'x') rs = lltype.malloc(RS, immortal=True) rs.x = '?' - x = cpu.bh_getfield_raw_i( - adr2int(llmemory.cast_ptr_to_adr(rs)), - descrfld_rx) + x = cpu.bh_getfield_raw_i(ptr2int(rs), descrfld_rx) assert x == ord('?') # - cpu.bh_setfield_raw_i( - adr2int(llmemory.cast_ptr_to_adr(rs)), - ord('!'), descrfld_rx) + cpu.bh_setfield_raw_i(ptr2int(rs), ord('!'), descrfld_rx) assert rs.x == '!' # @@ -3700,7 +3693,7 @@ def test_guards_nongc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') - v = adr2int(llmemory.cast_ptr_to_adr(x)) + v = ptr2int(x) vbox = InputArgInt(v) ops = [ (rop.GUARD_NONNULL, vbox, False), @@ -3907,8 +3900,7 @@ descr = self.cpu.arraydescrof(ARRAY) a = lltype.malloc(ARRAY, 10, flavor='raw') a[7] = -4242 - addr = llmemory.cast_ptr_to_adr(a) - abox = InputArgInt(adr2int(addr)) + abox = InputArgInt(ptr2int(a)) r1 = self.execute_operation(rop.GETARRAYITEM_RAW_I, [abox, InputArgInt(7)], 'int', descr=descr) assert r1 == -4242 @@ -3918,8 +3910,7 @@ ARRAY = rffi.CArray(lltype.Signed) descr = self.cpu.arraydescrof(ARRAY) a = lltype.malloc(ARRAY, 10, flavor='raw') - addr = llmemory.cast_ptr_to_adr(a) - abox = InputArgInt(adr2int(addr)) + abox = InputArgInt(ptr2int(a)) self.execute_operation(rop.SETARRAYITEM_RAW, [abox, InputArgInt(5), InputArgInt(12345)], 'void', descr=descr) @@ -4193,7 +4184,7 @@ value = intmask(0xFFEEDDCCBBAA9988) expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) - a_rawint = adr2int(llmemory.cast_ptr_to_adr(a)) + a_rawint = ptr2int(a) x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) @@ -4214,7 +4205,7 @@ value = intmask(0xFFEEDDCCBBAA9988) expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) - a_rawint = adr2int(llmemory.cast_ptr_to_adr(a)) + a_rawint = ptr2int(a) res = self.execute_operation(rop.GETARRAYITEM_RAW_I, [InputArgInt(a_rawint), InputArgInt(3)], 'int', descr=descrarray) @@ -5069,8 +5060,7 @@ a = lltype.malloc(A, 2, flavor='raw') a[0] = rffi.cast(rffi.SHORT, 666) a[1] = rffi.cast(rffi.SHORT, 777) - addr = llmemory.cast_ptr_to_adr(a) - a_int = adr2int(addr) + a_int = ptr2int(a) print 'a_int:', a_int self.execute_operation(rop.SETARRAYITEM_RAW, [ConstInt(a_int), ConstInt(0), ConstInt(-7654)], @@ -5104,8 +5094,7 @@ A = lltype.GcArray(OF) arraydescr = self.cpu.arraydescrof(A) a = lltype.malloc(A, 100) - addr = llmemory.cast_ptr_to_adr(a) - a_int = adr2int(addr) + a_int = ptr2int(a) a_ref = lltype.cast_opaque_ptr(llmemory.GCREF, a) for (start, length) in [(0, 100), (49, 49), (1, 98), (15, 9), (10, 10), (47, 0), @@ -5260,7 +5249,7 @@ xptr = lltype.malloc(X) xptr.parent.typeptr = xtp x_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, xptr)) - X_box = ConstInt(adr2int(llmemory.cast_ptr_to_adr(xtp))) + X_box = ConstInt(ptr2int(xtp)) ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) ytp.subclassrange_min = 2 @@ -5271,7 +5260,7 @@ yptr = lltype.malloc(Y) yptr.parent.parent.typeptr = ytp y_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, yptr)) - Y_box = ConstInt(adr2int(llmemory.cast_ptr_to_adr(ytp))) + Y_box = ConstInt(ptr2int(ytp)) ztp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) ztp.subclassrange_min = 4 @@ -5283,7 +5272,7 @@ zptr = lltype.malloc(Z) zptr.parent.typeptr = ztp z_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, zptr)) - Z_box = ConstInt(adr2int(llmemory.cast_ptr_to_adr(ztp))) + Z_box = ConstInt(ptr2int(ztp)) for num, arg, klass, is_subclass in [ (1, x_box, X_box, True), diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py --- a/rpython/jit/backend/test/test_ll_random.py +++ b/rpython/jit/backend/test/test_ll_random.py @@ -5,7 +5,7 @@ from rpython.jit.backend.test.test_random import getint, getref_base, getref from rpython.jit.metainterp.resoperation import ResOperation, rop, optypes from rpython.jit.metainterp.history import ConstInt, ConstPtr, getkind -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.jit.codewriter import heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rtyper.annlowlevel import llhelper @@ -219,9 +219,6 @@ # ____________________________________________________________ -def ConstAddr(addr): - return ConstInt(adr2int(addr)) - class GuardClassOperation(test_random.GuardOperation): def gen_guard(self, builder, r): ptrvars = [(v, S) for (v, S) in builder.ptrvars @@ -236,7 +233,7 @@ v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable = S._hints['vtable']._as_ptr() vtable2 = S2._hints['vtable']._as_ptr() - c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2)) + c_vtable2 = ConstInt(ptr2int(vtable2)) op = ResOperation(self.opnum, [v, c_vtable2], None) return op, (vtable == vtable2) @@ -250,7 +247,7 @@ builder.loop.operations.append(op) v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable2 = S2._hints['vtable']._as_ptr() - c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2)) + c_vtable2 = ConstInt(ptr2int(vtable2)) op = ResOperation(self.opnum, [op, c_vtable2], None) return op, False @@ -571,7 +568,7 @@ sum = %s return %s """ % (funcargs, sum, result)).compile() - d = {'intmask' : intmask} + d = {'intmask': intmask} exec code in d return subset, d['f'] @@ -587,8 +584,8 @@ vtableptr = v._hints['vtable']._as_ptr() d = { 'ptr': getref_base(S), - 'vtable' : vtableptr, - 'LLException' : LLException, + 'vtable': vtableptr, + 'LLException': LLException, } exec code in d return subset, d['f'], vtableptr @@ -616,7 +613,7 @@ RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) @@ -633,12 +630,12 @@ RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) - exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr)) + exc_box = ConstInt(ptr2int(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(builder.subset_of_intvars(r)) @@ -655,11 +652,11 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) - exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc)) + exc_box = ConstInt(ptr2int(exc)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(fail_subset) @@ -672,13 +669,13 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) - op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc)) + op._exc_box = ConstInt(ptr2int(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op @@ -691,7 +688,7 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) @@ -699,10 +696,10 @@ _, vtableptr = builder.get_random_structure_type_and_vtable(r) if vtableptr != exc: break - other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr)) + other_box = ConstInt(ptr2int(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], descr=builder.getfaildescr()) - op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc)) + op._exc_box = ConstInt(ptr2int(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op @@ -735,7 +732,7 @@ # TP = lltype.FuncType([lltype.Signed] * len(subset), RESULT_TYPE) ptr = llhelper(lltype.Ptr(TP), call_me) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr)) + c_addr = ConstInt(ptr2int(ptr)) args = [v_cond, c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -7,7 +7,7 @@ from rpython.jit.metainterp import quasiimmut from rpython.jit.metainterp.history import getkind from rpython.jit.metainterp.blackhole import BlackholeInterpreter -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.rlib import objectmodel from rpython.rlib.jit import _we_are_jitted @@ -1955,8 +1955,7 @@ if isinstance(op.args[0].value, str): pass # for tests only else: - func = adr2int( - llmemory.cast_ptr_to_adr(op.args[0].value)) + func = ptr2int(op.args[0].value) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) op1 = self.rewrite_call(op, 'residual_call', @@ -1983,8 +1982,7 @@ if isinstance(c_func.value, str): # in tests only func = c_func.value else: - func = adr2int( - llmemory.cast_ptr_to_adr(c_func.value)) + func = ptr2int(c_func.value) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) def _handle_int_special(self, op, oopspec_name, args): diff --git a/rpython/jit/codewriter/test/test_assembler.py b/rpython/jit/codewriter/test/test_assembler.py --- a/rpython/jit/codewriter/test/test_assembler.py +++ b/rpython/jit/codewriter/test/test_assembler.py @@ -5,7 +5,7 @@ from rpython.jit.codewriter.jitcode import MissingLiveness from rpython.jit.codewriter import longlong from rpython.jit.metainterp.history import AbstractDescr -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.flowspace.model import Constant from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rlib.rarithmetic import r_int, r_uint @@ -107,7 +107,7 @@ assert assembler.insns == {'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2} - f_int = adr2int(llmemory.cast_ptr_to_adr(f)) + f_int = ptr2int(f) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert jitcode.constants_r == [s_gcref] diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -944,8 +944,7 @@ def bhimpl_last_exception(self): real_instance = self.exception_last_value assert real_instance - adr = llmemory.cast_ptr_to_adr(real_instance.typeptr) - return adr2int(adr) + return ptr2int(real_instance.typeptr) @arguments("self", returns="r") def bhimpl_last_exc_value(self): 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 @@ -14,7 +14,7 @@ from rpython.jit.metainterp.resoperation import ResOperation, rop,\ AbstractValue, oparity, AbstractResOp, IntOp, RefOp, FloatOp,\ opclasses -from rpython.jit.metainterp.support import adr2int, int2adr +from rpython.jit.metainterp.support import ptr2int, int2adr from rpython.jit.codewriter import longlong import weakref from rpython.jit.metainterp import jitexc @@ -182,7 +182,7 @@ kind = getkind(T) if kind == "int": if isinstance(T, lltype.Ptr): - intval = adr2int(llmemory.cast_ptr_to_adr(x)) + intval = ptr2int(x) else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -13,7 +13,7 @@ from rpython.jit.metainterp.logger import Logger from rpython.jit.metainterp.optimizeopt.util import args_dict from rpython.jit.metainterp.resoperation import rop, OpHelpers, GuardResOp -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import adr2int, ptr2int from rpython.rlib.rjitlog import rjitlog as jl from rpython.rlib import nonconst, rstack from rpython.rlib.debug import debug_start, debug_stop, debug_print @@ -2676,8 +2676,7 @@ exception_obj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, exception) if exception_obj: - exc_class = adr2int( - llmemory.cast_ptr_to_adr(exception_obj.typeptr)) + exc_class = ptr2int(exception_obj.typeptr) else: exc_class = 0 assert self.history.trace is None @@ -2975,8 +2974,7 @@ def handle_possible_exception(self): if self.last_exc_value: - exception_box = ConstInt(adr2int( - llmemory.cast_ptr_to_adr(self.last_exc_value.typeptr))) + exception_box = ConstInt(ptr2int(self.last_exc_value.typeptr)) op = self.generate_guard(rop.GUARD_EXCEPTION, None, [exception_box]) val = lltype.cast_opaque_ptr(llmemory.GCREF, self.last_exc_value) diff --git a/rpython/jit/metainterp/support.py b/rpython/jit/metainterp/support.py --- a/rpython/jit/metainterp/support.py +++ b/rpython/jit/metainterp/support.py @@ -17,6 +17,15 @@ """ return llmemory.cast_int_to_adr(int) +def ptr2int(ptr): + """ + Cast a pointer to int. + + Returns an AddressAsInt object. + """ + addr = llmemory.cast_ptr_to_adr(ptr) + return llmemory.cast_adr_to_int(addr, "symbolic") + def int_signext(value, numbytes): b8 = numbytes * 8 a = r_uint(value) diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -1,7 +1,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.jit.metainterp import history -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.rlib.objectmodel import r_dict @@ -16,7 +16,6 @@ def cls_of_box(self, box): obj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, box.getref_base()) - cls = llmemory.cast_ptr_to_adr(obj.typeptr) - return history.ConstInt(adr2int(cls)) + return history.ConstInt(ptr2int(obj.typeptr)) llhelper = LLTypeHelper() diff --git a/rpython/jit/metainterp/virtualref.py b/rpython/jit/metainterp/virtualref.py --- a/rpython/jit/metainterp/virtualref.py +++ b/rpython/jit/metainterp/virtualref.py @@ -2,7 +2,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.jit.metainterp import history -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int from rpython.jit.metainterp.virtualizable import ( TOKEN_NONE, TOKEN_TRACING_RESCALL) from rpython.jit.codewriter import heaptracker @@ -34,8 +34,7 @@ self.jit_virtual_ref_vtable.name = rclass.alloc_array_name( 'jit_virtual_ref') # build some constants - adr = llmemory.cast_ptr_to_adr(self.jit_virtual_ref_vtable) - adr = adr2int(adr) + adr = ptr2int(self.jit_virtual_ref_vtable) self.jit_virtual_ref_const_class = history.ConstInt(adr) fielddescrof = self.cpu.fielddescrof self.descr_virtual_token = fielddescrof(self.JIT_VIRTUAL_REF, diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py --- a/rpython/jit/metainterp/warmstate.py +++ b/rpython/jit/metainterp/warmstate.py @@ -3,7 +3,7 @@ from rpython.jit.codewriter import support, longlong from rpython.jit.metainterp import resoperation, history, jitexc -from rpython.jit.metainterp.support import adr2int, int2adr +from rpython.jit.metainterp.support import ptr2int, int2adr from rpython.rlib.debug import debug_start, debug_stop, debug_print from rpython.rlib.debug import have_debug_prints_for from rpython.rlib.jit import PARAMETERS @@ -48,8 +48,7 @@ if lltype.typeOf(value).TO._gckind == 'gc': return lltype.cast_opaque_ptr(llmemory.GCREF, value) else: - adr = llmemory.cast_ptr_to_adr(value) - return adr2int(adr) + return ptr2int(value) elif isinstance(value, float): return longlong.getfloatstorage(value) else: @@ -82,8 +81,7 @@ res.setref_base(value) return res else: - adr = llmemory.cast_ptr_to_adr(value) - value = adr2int(adr) + value = ptr2int(value) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): diff --git a/rpython/jit/tool/oparser_model.py b/rpython/jit/tool/oparser_model.py --- a/rpython/jit/tool/oparser_model.py +++ b/rpython/jit/tool/oparser_model.py @@ -1,4 +1,4 @@ -from rpython.jit.metainterp.support import adr2int +from rpython.jit.metainterp.support import ptr2int class Boxes(object): pass @@ -23,8 +23,7 @@ @staticmethod def ptr_to_int(obj): - from rpython.rtyper.lltypesystem import llmemory - return adr2int(llmemory.cast_ptr_to_adr(obj)) + return ptr2int(obj) return LoopModel From pypy.commits at gmail.com Sat Apr 6 09:38:46 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 06 Apr 2019 06:38:46 -0700 (PDT) Subject: [pypy-commit] pypy winoverlapped: Replaced calls to _WinError with SetFromWindowsErr Message-ID: <5ca8abe6.1c69fb81.92dfa.29a7@mx.google.com> Author: andrewjlawrence Branch: winoverlapped Changeset: r96422:afa98536e149 Date: 2019-04-06 14:36 +0100 http://bitbucket.org/pypy/pypy/changeset/afa98536e149/ Log: Replaced calls to _WinError with SetFromWindowsErr diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py --- a/lib_pypy/_overlapped.py +++ b/lib_pypy/_overlapped.py @@ -20,7 +20,7 @@ GetVersion = _kernel32.GetVersion NULL = _ffi.NULL -from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z +from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z, SetFromWindowsErr import _winapi # @@ -181,7 +181,7 @@ if err != _winapi.ERROR_SUCCESS and \ err != _winapi.ERROR_NOT_FOUND and \ err != _winapi.ERROR_OPERATION_ABORTED: - raise _winapi._WinError() + SetFromWindowsErr(err) if self.overlapped[0].hEvent != 0: _winapi.CloseHandle(self.overlapped[0].hEvent) @@ -226,7 +226,7 @@ ### If we are to support xp we will need to dynamically load the below method result = _kernel32.CancelIoEx(self.handle, self.overlapped) if (not result and _kernel32.GetLastError() != _winapi.ERROR_NOT_FOUND): - raise _winapi._WinError() + SetFromWindowsErr(0) def WSARecv(self ,handle, size, flags): handle = _int2handle(handle) @@ -257,12 +257,12 @@ if self.error == _winapi.ERROR_BROKEN_PIPE: mark_as_completed(self.overlapped) - raise _winapi._WinError() + SetFromWindowsErr(self.error) elif self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING] : return None else: self.type = OverlappedType.TYPE_NOT_STARTED - raise _winapi._WinError() + SetFromWindowsErr(self.error) def WSASend(self ,handle, bufobj, flags): handle = _int2handle(handle) @@ -289,7 +289,7 @@ return None else: self.type = OverlappedType.TYPE_NOT_STARTED - raise _winapi._WinError() + SetFromWindowsErr(self.error) def getresult(self, wait=False): return self.GetOverlappedResult(wait) @@ -313,7 +313,7 @@ mark_as_completed(self.overlapped) return True else: - raise _winapi._WinError() + SetFromWindowsErr(err) def ReadFile(self, handle, size): self.type = OverlappedType.TYPE_READ @@ -333,12 +333,12 @@ if err == _winapi.ERROR_BROKEN_PIPE: mark_as_completed(self.overlapped) - raise _winapi._WinError() + SetFromWindowsErr(err) elif err in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING]: return None else: self.type = OverlappedType.TYPE_NOT_STARTED - raise _winapi._WinError() + SetFromWindowsErr(err) def WriteFile(self, handle, buffer): self.handle = _int2handle(handle) @@ -362,7 +362,7 @@ return None else: self.type = OverlappedType.TYPE_NOT_STARTED - raise _winapi.WinError() + SetFromWindowsErr(self.error) def AcceptEx(self, listensocket, acceptsocket): listensocket = _int2handle(listensocket) @@ -393,7 +393,7 @@ return None else: self.type = OverlappedType.TYPE_NOT_STARTED - raise _winapi.WinError() + SetFromWindowsErr(0) def DisconnectEx(self, socket, flags): xxx @@ -428,7 +428,7 @@ return None else: self.type = OverlappedType.TYPE_NOT_STARTED - raise _winapi.WinError() + SetFromWindowsErr(0) @property def pending(self): @@ -465,7 +465,7 @@ completionkey, numberofconcurrentthreads) if result == _ffi.NULL: - raise _winapi._WinError() + raise SetFromWindowsErr(0) return result @@ -516,7 +516,7 @@ miliseconds, _kernel32.WT_EXECUTEINWAITTHREAD | _kernel32.WT_EXECUTEONLYONCE) if not ret: - raise _winapi._WinError() + SetFromWindowsErr(0) return _handle2int(newwaitobject[0]) @@ -533,7 +533,7 @@ err = _kernel32.GetLastError() if handle == INVALID_HANDLE_VALUE or err == _winapi.ERROR_PIPE_BUSY: - raise _winapi._WinError() + SetFromWindowsErr(err) return _handle2int(handle) @@ -542,9 +542,9 @@ waitevent = _int2handle(event) ret = _kernel32.UnregisterWaitEx(waithandle, waitevent) - + if not ret: - raise _winapi._WinError() + SetFromWindowsErr(0) def UnregisterWait(handle): handle = _int2handle(handle) @@ -552,7 +552,7 @@ ret = _kernel32.UnregisterWait(handle) if not ret: - raise _winapi._WinError() + SetFromWindowsErr(0) def BindLocal(socket, family): socket = _int2handle(socket) @@ -573,21 +573,7 @@ raise ValueError() if result == SOCKET_ERROR: - raise _winapi._WinError() - - -# In CPython this function converts a windows error into a python object -# Not sure what we should do here. -def SetFromWindowsErr(err): - if err == _winapi.ERROR_CONNECTION_REFUSED: - type = ConnectionRefusedError; - elif err == _winapi.ERROR_CONNECTION_ABORTED: - type = ConnectionAbortedError; - else: - type = WindowsError; - - return _winapi._WinError(type); - + SetFromWindowsErr(0) def HasOverlappedIoCompleted(overlapped): return (overlapped.Internal != STATUS_PENDING) diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -17,13 +17,26 @@ NULL = _ffi.NULL # Now the _subprocess module implementation - - def _WinError(type=WindowsError): code, message = _ffi.getwinerror() excep = type(None, message, None ,code) raise excep +# In CPython this function converts a windows error into a python object +# Not sure what we should do here. +def SetFromWindowsErr(err): + if err == 0: + err = _kernel32.GetLastError() + + if err == ERROR_CONNECTION_REFUSED: + type = ConnectionRefusedError + elif err == ERROR_CONNECTION_ABORTED: + type = ConnectionAbortedError + else: + type = WindowsError + + return _WinError(type) + def _int2handle(val): return _ffi.cast("HANDLE", val) @@ -38,20 +51,20 @@ res = _kernel32.CreatePipe(handles, handles + 1, NULL, size) if not res: - raise _WinError() + SetFromWindowsErr(0) return _handle2int(handles[0]), _handle2int(handles[1]) def CreateNamedPipe(*args): handle = _kernel32.CreateNamedPipeW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() + SetFromWindowsErr(0) return _handle2int(handle) def CreateFile(*args): handle = _kernel32.CreateFileW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() + SetFromWindowsErr(0) return _handle2int(handle) def SetNamedPipeHandleState(namedpipe, mode, max_collection_count, collect_data_timeout): @@ -93,7 +106,8 @@ raise RuntimeError('deleting an overlapped struct with a pending operation not supported') @property - def event(self): + def event(self): + xxx return None def GetOverlappedResult(self, wait): @@ -142,10 +156,10 @@ _kernel32.SetEvent(ov.overlapped[0].hEvent) else: del ov - raise _WinError() + SetFromWindowsErr(err) return ov elif not success: - raise _WinError() + SetFromWindowsErr(0) def GetCurrentProcess(): return _handle2int(_kernel32.GetCurrentProcess()) From pypy.commits at gmail.com Sat Apr 6 13:00:35 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 06 Apr 2019 10:00:35 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Move cls_of_box() to cpu and kill rpython.jit.metainterp.typesystem Message-ID: <5ca8db33.1c69fb81.63afa.2908@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96423:690f56c5e4e9 Date: 2019-04-06 02:51 +0100 http://bitbucket.org/pypy/pypy/changeset/690f56c5e4e9/ Log: Move cls_of_box() to cpu and kill rpython.jit.metainterp.typesystem diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -150,7 +150,6 @@ EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) - typesystem = 'lltype' namespace = locals().copy() class TestRegallocSimple(CustomBaseTestRegalloc): diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -1,6 +1,9 @@ import weakref from rpython.rlib.debug import debug_start, debug_print, debug_stop from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.rclass import OBJECTPTR +from rpython.jit.metainterp.history import ConstInt +from rpython.jit.metainterp.support import ptr2int class CPUTotalTracker(object): total_compiled_loops = 0 @@ -9,8 +12,6 @@ total_freed_bridges = 0 class AbstractCPU(object): - from rpython.jit.metainterp.typesystem import llhelper as ts - supports_floats = False supports_longlong = False # ^^^ This is only useful on 32-bit platforms. If True, @@ -194,6 +195,10 @@ x = llmemory.cast_int_to_adr(x) return llmemory.cast_adr_to_ptr(x, TYPE) + def cls_of_box(self, box): + obj = lltype.cast_opaque_ptr(OBJECTPTR, box.getref_base()) + return ConstInt(ptr2int(obj.typeptr)) + # ---------- the backend-dependent operations ---------- diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -4,7 +4,8 @@ from rpython.jit.metainterp.jitexc import get_llexception, reraise from rpython.jit.metainterp import jitexc from rpython.jit.metainterp.history import MissingValue -from rpython.jit.metainterp.support import adr2int, int2adr, int_signext +from rpython.jit.metainterp.support import ( + adr2int, int2adr, ptr2int, int_signext) from rpython.rlib import longlong2float from rpython.rlib.debug import ll_assert, make_sure_not_resized from rpython.rlib.debug import check_annotation diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py b/rpython/jit/metainterp/optimizeopt/bridgeopt.py --- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py +++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py @@ -142,7 +142,7 @@ class_known = bitfield & mask mask >>= 1 if class_known: - cls = optimizer.cpu.ts.cls_of_box(frontend_boxes[i]) + cls = optimizer.cpu.cls_of_box(frontend_boxes[i]) optimizer.make_constant_class(box, cls) # heap knowledge diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py --- a/rpython/jit/metainterp/optimizeopt/info.py +++ b/rpython/jit/metainterp/optimizeopt/info.py @@ -15,7 +15,7 @@ class AbstractInfo(AbstractValue): _attrs_ = () - + is_info_class = True def force_box(self, op, optforce): @@ -89,7 +89,7 @@ class NonNullPtrInfo(PtrInfo): _attrs_ = ('last_guard_pos',) last_guard_pos = -1 - + def is_nonnull(self): return True @@ -469,7 +469,7 @@ def setitem_raw(self, offset, itemsize, descr, itemop): self.parent.setitem_raw(self.offset+offset, itemsize, descr, itemop) - + def _force_elements(self, op, optforce, descr): if self.parent.is_virtual(): self.parent._force_elements(op, optforce, descr) @@ -643,7 +643,7 @@ return 0 # annotation hack one_size = len(all_fdescrs) return index * one_size + fielddescr.get_field_descr().get_index() - + def setinteriorfield_virtual(self, index, fielddescr, fld): index = self._compute_index(index, fielddescr) self._items[index] = fld @@ -693,7 +693,7 @@ class ConstPtrInfo(PtrInfo): _attrs_ = ('_const',) - + def __init__(self, const): self._const = const @@ -719,7 +719,7 @@ if info is None: info = ArrayPtrInfo(descr) optheap.const_infos[ref] = info - return info + return info def getfield(self, fielddescr, optheap=None): info = self._get_info(fielddescr.get_parent_descr(), optheap) @@ -755,7 +755,7 @@ # guard_gc_type if not cpu.check_is_object(self._const.getref_base()): return None - return cpu.ts.cls_of_box(self._const) + return cpu.cls_of_box(self._const) def same_info(self, other): if not isinstance(other, ConstPtrInfo): @@ -804,7 +804,7 @@ return -1 return len(s) elif mode is vstring.mode_unicode: - s = self._unpack_str(vstring.mode_unicode) + s = self._unpack_str(vstring.mode_unicode) if s is None: return -1 return len(s) @@ -835,7 +835,7 @@ targetbox, CONST_0, offsetbox, lgt, mode) - + class FloatConstInfo(AbstractInfo): def __init__(self, const): self._const = const diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -393,7 +393,7 @@ # class cannot possibly match (see test_issue2926) if info and info.is_constant(): c = self.get_box_replacement(op.getarg(0)) - vtable = optimizer.cpu.ts.cls_of_box(c).getint() + vtable = optimizer.cpu.cls_of_box(c).getint() if optimizer._check_subclass(vtable, op.getarg(1).getint()): return raise InvalidLoop("GUARD_SUBCLASS(const) proven to always fail") @@ -482,7 +482,7 @@ 'guard that it is not NULL') previous_classbox = info.get_known_class(self.optimizer.cpu) if previous_classbox is not None: - expected_classbox = self.optimizer.cpu.ts.cls_of_box(c_value) + expected_classbox = self.optimizer.cpu.cls_of_box(c_value) assert expected_classbox is not None if not previous_classbox.same_constant( expected_classbox): diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py @@ -31,13 +31,13 @@ class BaseTestGenerateGuards(BaseTest): def setup_class(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) self.knownclass_info = not_virtual(self.cpu, 'r', value) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.node2addr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.node2addr)) value = info.InstancePtrInfo(None, classbox) self.knownclass_info2 = not_virtual(self.cpu, 'r', value) - + def guards(self, info1, info2, box, runtime_box, expected, inputargs=None): if inputargs is None: inputargs = [box] @@ -97,13 +97,13 @@ # subsequently in all cases, so we just need to ensure that this case does # not cause segfaults. optimizer = FakeOptimizer(self.cpu) - classbox1 = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox1 = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) innervalue1 = info.InstancePtrInfo( known_class=classbox1, is_virtual=True, descr=self.valuedescr.get_parent_descr()) for field in self.valuedescr.get_parent_descr().get_all_fielddescrs(): innervalue1.setfield(field, None, ConstInt(42)) - classbox2 = self.cpu.ts.cls_of_box(InputArgRef(self.myptr3)) + classbox2 = self.cpu.cls_of_box(InputArgRef(self.myptr3)) innervalue2 = info.InstancePtrInfo( known_class=classbox2, is_virtual=True, descr=self.valuedescr3.get_parent_descr()) @@ -175,7 +175,7 @@ ptr = info.PtrInfo() nonnull = info.NonNullPtrInfo() - clsbox = self.cpu.ts.cls_of_box(InputArgRef(self.myptr)) + clsbox = self.cpu.cls_of_box(InputArgRef(self.myptr)) knownclass = info.InstancePtrInfo(known_class=clsbox) const = info.ConstPtrInfo(ConstPtr(self.myptr)) inorder = [ptr, nonnull, knownclass, const] @@ -264,10 +264,10 @@ nonnull_info = not_virtual(self.cpu, 'r', info.NonNullPtrInfo()) - classbox1 = self.cpu.ts.cls_of_box(ConstPtr(self.nodeaddr)) + classbox1 = self.cpu.cls_of_box(ConstPtr(self.nodeaddr)) knownclass_info = not_virtual(self.cpu, 'r', info.InstancePtrInfo(None, classbox1)) - classbox2 = self.cpu.ts.cls_of_box(ConstPtr(self.node2addr)) + classbox2 = self.cpu.cls_of_box(ConstPtr(self.node2addr)) knownclass2_info = not_virtual(self.cpu, 'r', info.InstancePtrInfo(None, classbox2)) @@ -455,20 +455,20 @@ self.check_no_guards(info1, info2) def test_known_class(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value1 = info.InstancePtrInfo(None, classbox) info1 = not_virtual(self.cpu, 'r', value1) info2 = not_virtual(self.cpu, 'r', None) expected = """ [p0] - guard_nonnull_class(p0, ConstClass(node_vtable)) [] + guard_nonnull_class(p0, ConstClass(node_vtable)) [] """ self.guards(info1, info2, InputArgRef(), InputArgRef(self.nodeaddr), expected) self.check_invalid(info1, info2, InputArgRef()) def test_known_class_value(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value1 = info.InstancePtrInfo(None, classbox) box = InputArgRef() guards = [] @@ -493,7 +493,7 @@ self.compare(guards, expected, [box]) def test_equal_inputargs(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) vstate1 = VirtualState([knownclass_info, knownclass_info]) @@ -531,7 +531,7 @@ def test_generate_guards_on_virtual_fields_matches_array(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) innervalue1 = info.InstancePtrInfo(None, classbox) innerinfo1 = not_virtual(self.cpu, 'r', innervalue1) innerinfo1.position = 1 @@ -561,7 +561,7 @@ self.guards(info1, info2, runtime_box, runtime_box, expected, [box]) def test_generate_guards_on_virtual_fields_matches_instance(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) innervalue1 = info.InstancePtrInfo(None, classbox) innerinfo1 = not_virtual(self.cpu, 'r', innervalue1) innerinfo1.position = 1 @@ -589,7 +589,7 @@ self.guards(info1, info2, nodebox, runtime_box, expected, [node2box]) def test_generate_guards_on_virtual_fields_matches_struct(self): - constclassbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + constclassbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) innervalue1 = info.InstancePtrInfo(None, constclassbox) innerinfo1 = not_virtual(self.cpu, 'r', innervalue1) innerinfo1.position = 1 @@ -620,7 +620,7 @@ [node2box]) def test_generate_guards_on_virtual_fields_matches_arraystruct(self): - constclassbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + constclassbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) innervalue1 = info.InstancePtrInfo(None, constclassbox) innerinfo1 = not_virtual(self.cpu, 'r', innervalue1) innerinfo1.position = 1 @@ -630,7 +630,7 @@ NODE = lltype.Struct('NODE', ('x', llmemory.GCREF)) ARRAY = lltype.GcArray(NODE) descr = self.cpu.fielddescrof(NODE, 'x') - + arraydescr = self.cpu.arraydescrof(ARRAY) info1 = VArrayStructStateInfo(arraydescr, [descr], 1) @@ -680,7 +680,7 @@ unknown_info2 = not_virtual(self.cpu, 'r', info.InstancePtrInfo()) info3.fieldstate = [unknown_info1, unknown_info2] - vstate3 = VirtualState([info3]) + vstate3 = VirtualState([info3]) assert vstate3.generalization_of(vstate2, FakeOptimizer(self.cpu)) assert vstate3.generalization_of(vstate1, FakeOptimizer(self.cpu)) assert not vstate2.generalization_of(vstate3, FakeOptimizer(self.cpu)) @@ -688,7 +688,7 @@ def test_virtuals_with_nonmatching_fields(self): info1 = VirtualStateInfo(ConstInt(42), [1, 2]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info1.fieldstate = [knownclass_info, knownclass_info] @@ -696,7 +696,7 @@ assert vstate1.generalization_of(vstate1, FakeOptimizer(self.cpu)) info2 = VirtualStateInfo(ConstInt(42), [1, 2]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.node2addr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.node2addr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info2.fieldstate = [knownclass_info, knownclass_info] @@ -708,7 +708,7 @@ def test_virtuals_with_nonmatching_descrs(self): info1 = VirtualStateInfo(ConstInt(42), [10, 20]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info1.fieldstate = [knownclass_info, knownclass_info] @@ -716,7 +716,7 @@ assert vstate1.generalization_of(vstate1, FakeOptimizer(self.cpu)) info2 = VirtualStateInfo(ConstInt(42), [1, 2]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.node2addr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.node2addr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info2.fieldstate = [knownclass_info, knownclass_info] @@ -725,10 +725,10 @@ assert not vstate2.generalization_of(vstate1, FakeOptimizer(self.cpu)) assert not vstate1.generalization_of(vstate2, FakeOptimizer(self.cpu)) - + def test_virtuals_with_nonmatching_classes(self): info1 = VirtualStateInfo(ConstInt(42), [1, 2]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info1.fieldstate = [knownclass_info, knownclass_info] @@ -736,7 +736,7 @@ assert vstate1.generalization_of(vstate1, FakeOptimizer(self.cpu)) info2 = VirtualStateInfo(ConstInt(7), [1, 2]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.node2addr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.node2addr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info2.fieldstate = [knownclass_info, knownclass_info] @@ -748,7 +748,7 @@ def test_nonvirtual_is_not_virtual(self): info1 = VirtualStateInfo(ConstInt(42), [1, 2]) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info1.fieldstate = [knownclass_info, knownclass_info] @@ -764,7 +764,7 @@ def test_arrays_with_nonmatching_fields(self): info1 = VArrayStateInfo(42) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info1.fieldstate = [knownclass_info, knownclass_info] @@ -772,7 +772,7 @@ assert vstate1.generalization_of(vstate1, FakeOptimizer(self.cpu)) info2 = VArrayStateInfo(42) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.node2addr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.node2addr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info2.fieldstate = [knownclass_info, knownclass_info] @@ -784,7 +784,7 @@ def test_arrays_of_different_sizes(self): info1 = VArrayStateInfo(42) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info1.fieldstate = [knownclass_info, knownclass_info] @@ -792,7 +792,7 @@ assert vstate1.generalization_of(vstate1, FakeOptimizer(self.cpu)) info2 = VArrayStateInfo(42) - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.node2addr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.node2addr)) value = info.InstancePtrInfo(None, classbox) knownclass_info = not_virtual(self.cpu, 'r', value) info2.fieldstate = [knownclass_info] @@ -815,7 +815,7 @@ assert not vstate2.generalization_of(vstate1, FakeOptimizer(self.cpu)) assert not vstate1.generalization_of(vstate2, FakeOptimizer(self.cpu)) - + def test_nonvirtual_is_not_array(self): info1 = VArrayStateInfo(42) info1.fieldstate = [self.knownclass_info, self.knownclass_info] @@ -827,10 +827,10 @@ assert not vstate2.generalization_of(vstate1, FakeOptimizer(self.cpu)) assert not vstate1.generalization_of(vstate2, FakeOptimizer(self.cpu)) - + def test_crash_varay_clear(self): - classbox = self.cpu.ts.cls_of_box(InputArgRef(self.nodeaddr)) + classbox = self.cpu.cls_of_box(InputArgRef(self.nodeaddr)) innervalue1 = info.InstancePtrInfo(None, classbox) innerinfo1 = not_virtual(self.cpu, 'r', innervalue1) innerinfo1.position = 1 @@ -873,13 +873,13 @@ values) data = compile.BridgeCompileData(trace, runtime_boxes, enable_opts=self.enable_opts, inline_short_preamble=True) - + info, newops = optimize_trace(metainterp_sd, None, data) if info.final(): bridge.operations = newops bridge.inputargs = info.inputargs return info - + def optimize_bridge(self, loops, bridge, expected, expected_target='Loop', boxvalues=None): if isinstance(loops, str): @@ -966,7 +966,7 @@ """ self.optimize_bridge(loop, bridge, expected, boxvalues=[self.myptr]) - def test_cached_unused_nonnull(self): + def test_cached_unused_nonnull(self): loop = """ [p0] p1 = getfield_gc_r(p0, descr=nextdescr) @@ -985,10 +985,10 @@ p1 = getfield_gc_r(p0, descr=nextdescr) guard_nonnull(p1) [] jump(p0) - """ + """ self.optimize_bridge(loop, bridge, expected, boxvalues=[self.myptr]) - def test_cached_invalid_nonnull(self): + def test_cached_invalid_nonnull(self): loop = """ [p0] p1 = getfield_gc_r(p0, descr=nextdescr) @@ -998,7 +998,7 @@ bridge = """ [p0] p1 = getfield_gc_r(p0, descr=nextdescr) - guard_value(p1, ConstPtr(nullptr)) [] + guard_value(p1, ConstPtr(nullptr)) [] jump(p0) """ self.optimize_bridge(loop, bridge, bridge, 'Preamble', @@ -1074,7 +1074,7 @@ guard_is_object(p0) [] guard_subclass(p0, ConstClass(node_vtable)) [] p1 = getfield_gc_r(p0, descr=nextdescr) - guard_value(p1, ConstPtr(myptr)) [] + guard_value(p1, ConstPtr(myptr)) [] jump(p0) """ self.optimize_bridge(loop, bridge, expected, 'Loop', [self.myptr]) @@ -1159,7 +1159,7 @@ guard_nonnull(p1) [] guard_is_object(p1) [] guard_class(p1, ConstClass(node_vtable)) [] - jump(p0) + jump(p0) """ self.optimize_bridge(loop, bridge, expected, 'Loop', [self.myptr]) @@ -1190,7 +1190,7 @@ ifoo = arraylen_gc(p0, descr=arraydescr) i3 = getarrayitem_gc_i(p0, 10, descr=arraydescr) jump(p0, i3) - """ + """ self.optimize_bridge(loop, bridge, expected, 'Loop0', [self.myptr]) bridge = """ [p0] @@ -1231,10 +1231,10 @@ [p0] p1 = getfield_gc_r(p0, descr=nextdescr) i2 = getarrayitem_gc_i(p1, 15, descr=arraydescr) - i3 = arraylen_gc(p1, descr=arraydescr) # Should be killed by backend + i3 = arraylen_gc(p1, descr=arraydescr) # Should be killed by backend i4 = getarrayitem_gc_i(p1, 10, descr=arraydescr) jump(p0, p1, i4) - """ + """ self.optimize_bridge(loop, bridge, expected) bridge = """ [p0] @@ -1251,7 +1251,7 @@ guard_true(i4) [] i5 = getarrayitem_gc_i(p1, 10, descr=arraydescr) jump(p0, p1, i5) - """ + """ self.optimize_bridge(loop, bridge, expected) bridge = """ [p0] @@ -1270,7 +1270,7 @@ guard_true(i4) [] i5 = getarrayitem_gc_i(p1, 10, descr=arraydescr) jump(p0, p1, i5) - """ + """ self.optimize_bridge(loop, bridge, expected, 'Loop', [self.myptr]) def test_cached_setarrayitem_gc(self): @@ -1308,7 +1308,7 @@ loop = """ [p5] i10 = getfield_gc_i(p5, descr=valuedescr) - call_n(i10, descr=nonwritedescr) + call_n(i10, descr=nonwritedescr) setfield_gc(p5, 1, descr=valuedescr) jump(p5) """ @@ -1344,7 +1344,7 @@ i10 = getfield_gc_i(p5, descr=valuedescr) i11 = getfield_gc_i(p6, descr=chardescr) call_n(i10, i11, descr=nonwritedescr) - setfield_gc(p6, i10, descr=nextdescr) + setfield_gc(p6, i10, descr=nextdescr) jump(p5, p6) """ bridge = """ @@ -1379,7 +1379,7 @@ def setup_class(self): py.test.skip("rewrite") - + def test_short_box_duplication_direct(self): class Optimizer(FakeOptimizer): def produce_potential_short_preamble_ops(_self, sb): @@ -1436,7 +1436,7 @@ if op and op.result == int_neg.getarg(0)] assert len(getfield) == 1 assert getfield[0].getarg(0) in [self.p1, self.p2] - + def test_prioritize2(self): class Optimizer(FakeOptimizer): def produce_potential_short_preamble_ops(_self, sb): @@ -1454,7 +1454,7 @@ if op and op.result == int_neg.getarg(0)] assert len(getfield) == 1 assert getfield[0].getarg(0) == self.p2 - + def test_prioritize3(self): class Optimizer(FakeOptimizer): def produce_potential_short_preamble_ops(_self, sb): diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py @@ -596,14 +596,14 @@ raise VirtualStatesCantMatch('trying to match ptr with non-ptr??!') if other.level == LEVEL_UNKNOWN: if (runtime_box and runtime_box.nonnull() and - self.known_class.same_constant(cpu.ts.cls_of_box(runtime_box))): + self.known_class.same_constant(cpu.cls_of_box(runtime_box))): op = ResOperation(rop.GUARD_NONNULL_CLASS, [box, self.known_class]) extra_guards.append(op) else: raise VirtualStatesCantMatch("other's class is unknown") elif other.level == LEVEL_NONNULL: if (runtime_box and self.known_class.same_constant( - cpu.ts.cls_of_box(runtime_box))): + cpu.cls_of_box(runtime_box))): op = ResOperation(rop.GUARD_CLASS, [box, self.known_class]) extra_guards.append(op) else: @@ -615,7 +615,7 @@ else: assert other.level == LEVEL_CONSTANT if (other.constbox.nonnull() and - self.known_class.same_constant(cpu.ts.cls_of_box(other.constbox))): + self.known_class.same_constant(cpu.cls_of_box(other.constbox))): pass else: raise VirtualStatesCantMatch("classes don't match") diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1383,7 +1383,8 @@ exc_value = self.metainterp.last_exc_value assert exc_value assert self.metainterp.class_of_last_exc_is_const - return self.metainterp.cpu.ts.cls_of_box(ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, exc_value))) + exc_cls = rclass.ll_cast_to_object(exc_value).typeptr + return ConstInt(ptr2int(exc_cls)) @arguments() def opimpl_last_exc_value(self): @@ -1583,7 +1584,7 @@ return promoted_box def cls_of_box(self, box): - return self.metainterp.cpu.ts.cls_of_box(box) + return self.metainterp.cpu.cls_of_box(box) @specialize.arg(1) def execute(self, opnum, *argboxes): diff --git a/rpython/jit/metainterp/test/test_bridgeopt.py b/rpython/jit/metainterp/test/test_bridgeopt.py --- a/rpython/jit/metainterp/test/test_bridgeopt.py +++ b/rpython/jit/metainterp/test/test_bridgeopt.py @@ -15,18 +15,14 @@ from hypothesis import strategies, given -class FakeTS(object): + +class FakeCPU(object): def __init__(self, dct): self.dct = dct def cls_of_box(self, box): return self.dct[box] - -class FakeCPU(object): - def __init__(self, dct): - self.ts = FakeTS(dct) - class FakeOptimizer(object): metainterp_sd = None optheap = None diff --git a/rpython/jit/metainterp/test/test_compile.py b/rpython/jit/metainterp/test/test_compile.py --- a/rpython/jit/metainterp/test/test_compile.py +++ b/rpython/jit/metainterp/test/test_compile.py @@ -5,7 +5,7 @@ from rpython.jit.metainterp.compile import compile_tmp_callback from rpython.jit.metainterp import jitexc from rpython.rlib.rjitlog import rjitlog as jl -from rpython.jit.metainterp import jitprof, typesystem, compile +from rpython.jit.metainterp import jitprof, compile from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin from rpython.jit.tool.oparser import parse, convert_loop_to_trace from rpython.jit.metainterp.optimizeopt import ALL_OPTS_DICT @@ -19,7 +19,6 @@ class tracker: pass - ts = typesystem.llhelper def __init__(self): self.seen = [] diff --git a/rpython/jit/metainterp/test/test_quasiimmut.py b/rpython/jit/metainterp/test/test_quasiimmut.py --- a/rpython/jit/metainterp/test/test_quasiimmut.py +++ b/rpython/jit/metainterp/test/test_quasiimmut.py @@ -4,7 +4,6 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE -from rpython.jit.metainterp import typesystem from rpython.jit.metainterp.quasiimmut import QuasiImmut from rpython.jit.metainterp.quasiimmut import get_current_qmut_instance from rpython.jit.metainterp.test.support import LLJitMixin @@ -23,8 +22,6 @@ assert not foo.mutate_x class FakeCPU: - ts = typesystem.llhelper - def bh_getfield_gc_r(self, gcref, fielddescr): assert fielddescr == mutatefielddescr foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref) diff --git a/rpython/jit/metainterp/test/test_warmspot.py b/rpython/jit/metainterp/test/test_warmspot.py --- a/rpython/jit/metainterp/test/test_warmspot.py +++ b/rpython/jit/metainterp/test/test_warmspot.py @@ -578,7 +578,6 @@ class TestWarmspotDirect(object): def setup_class(cls): - from rpython.jit.metainterp.typesystem import llhelper from rpython.jit.codewriter.support import annotate from rpython.jit.metainterp.warmspot import WarmRunnerDesc from rpython.rtyper.rclass import OBJECT, OBJECT_VTABLE @@ -615,7 +614,6 @@ supports_floats = False supports_longlong = False supports_singlefloats = False - ts = llhelper translate_support_code = False stats = "stats" diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py deleted file mode 100644 --- a/rpython/jit/metainterp/typesystem.py +++ /dev/null @@ -1,21 +0,0 @@ -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper import rclass -from rpython.jit.metainterp import history -from rpython.jit.metainterp.support import ptr2int -from rpython.rlib.objectmodel import r_dict - - -class TypeSystemHelper(object): - - def _freeze_(self): - return True - -class LLTypeHelper(TypeSystemHelper): - - name = 'lltype' - - def cls_of_box(self, box): - obj = lltype.cast_opaque_ptr(rclass.OBJECTPTR, box.getref_base()) - return history.ConstInt(ptr2int(obj.typeptr)) - -llhelper = LLTypeHelper() diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py --- a/rpython/jit/metainterp/virtualizable.py +++ b/rpython/jit/metainterp/virtualizable.py @@ -284,7 +284,6 @@ force_virtualizable_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs - ts = self.warmrunnerdesc.cpu.ts FUNC = lltype.FuncType([self.VTYPEPTR], lltype.Void) funcptr = self.warmrunnerdesc.helper_func( lltype.Ptr(FUNC), force_virtualizable_if_necessary) diff --git a/rpython/jit/tool/oparser_model.py b/rpython/jit/tool/oparser_model.py --- a/rpython/jit/tool/oparser_model.py +++ b/rpython/jit/tool/oparser_model.py @@ -8,7 +8,6 @@ from rpython.jit.metainterp.history import TreeLoop, JitCellToken from rpython.jit.metainterp.history import ConstInt, ConstPtr, ConstFloat from rpython.jit.metainterp.history import BasicFailDescr, BasicFinalDescr, TargetToken - from rpython.jit.metainterp.typesystem import llhelper from rpython.jit.metainterp.opencoder import Trace from rpython.jit.metainterp.history import get_const_ptr_for_string @@ -119,11 +118,6 @@ def ptr_to_int(obj): return id(obj) - class llhelper(object): - pass - - MockLoopModel.llhelper.BoxRef = MockLoopModel.BoxRef - return MockLoopModel From pypy.commits at gmail.com Sat Apr 6 17:37:45 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 06 Apr 2019 14:37:45 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: fix translation and tests Message-ID: <5ca91c29.1c69fb81.25964.2e8f@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96424:8125e097bcdb Date: 2019-04-06 22:37 +0100 http://bitbucket.org/pypy/pypy/changeset/8125e097bcdb/ Log: fix translation and tests diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -1896,7 +1896,7 @@ T_box = None else: vtable = vtable_for_T - T_box = ConstInt(ptr2int(vtable_for_T_addr)) + T_box = ConstInt(ptr2int(vtable_for_T)) descr = cpu.sizeof(T, vtable) return t_box, T_box, descr diff --git a/rpython/jit/metainterp/support.py b/rpython/jit/metainterp/support.py --- a/rpython/jit/metainterp/support.py +++ b/rpython/jit/metainterp/support.py @@ -25,6 +25,7 @@ """ addr = llmemory.cast_ptr_to_adr(ptr) return llmemory.cast_adr_to_int(addr, "symbolic") +ptr2int._annspecialcase_ = 'specialize:arglltype(0)' def int_signext(value, numbytes): b8 = numbytes * 8 From pypy.commits at gmail.com Sat Apr 6 19:10:23 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 06 Apr 2019 16:10:23 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: fix import from deleted file Message-ID: <5ca931df.1c69fb81.e82c6.25ec@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96425:e0a3d70a60f7 Date: 2019-04-07 00:09 +0100 http://bitbucket.org/pypy/pypy/changeset/e0a3d70a60f7/ Log: fix import from deleted file diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -13,7 +13,6 @@ from pypy.module.pypyjit.interp_jit import pypyjitdriver from pypy.module.pypyjit.hooks import pypy_hooks from rpython.jit.tool.oparser import parse -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.jit import JitDebugInfo, AsmInfo, Counters @@ -31,7 +30,7 @@ class MockSD(object): class cpu(object): - ts = llhelper + pass jitdrivers_sd = [MockJitDriverSD] From pypy.commits at gmail.com Mon Apr 8 18:12:42 2019 From: pypy.commits at gmail.com (yodada) Date: Mon, 08 Apr 2019 15:12:42 -0700 (PDT) Subject: [pypy-commit] pypy record-exact-value: ( yodada, cfbolz ) Message-ID: <5cabc75a.1c69fb81.7096e.2c98@mx.google.com> Author: Lin Cheng Branch: record-exact-value Changeset: r96426:a73fe4ae5748 Date: 2019-04-08 18:11 -0400 http://bitbucket.org/pypy/pypy/changeset/a73fe4ae5748/ Log: ( yodada, cfbolz ) Added the missing definition of OP_JIT_RECORD_EXACT_VALUE in rpython/translator/c/src/support.h diff --git a/rpython/translator/c/src/support.h b/rpython/translator/c/src/support.h --- a/rpython/translator/c/src/support.h +++ b/rpython/translator/c/src/support.h @@ -7,6 +7,7 @@ #define RUNNING_ON_LLINTERP 0 #define OP_JIT_RECORD_EXACT_CLASS(i, c, r) /* nothing */ +#define OP_JIT_RECORD_EXACT_VALUE(i, c, r) /* nothing */ #define FAIL_OVF(msg) _RPyRaiseSimpleException(RPyExc_OverflowError) From pypy.commits at gmail.com Tue Apr 9 11:34:44 2019 From: pypy.commits at gmail.com (rlamy) Date: Tue, 09 Apr 2019 08:34:44 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Document branch Message-ID: <5cacbb94.1c69fb81.345aa.619e@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96427:135a7f91ea44 Date: 2019-04-09 16:17 +0100 http://bitbucket.org/pypy/pypy/changeset/135a7f91ea44/ Log: Document branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -9,3 +9,6 @@ Fix typo +.. branch: jit-cleanup + +Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ From pypy.commits at gmail.com Tue Apr 9 14:20:35 2019 From: pypy.commits at gmail.com (rlamy) Date: Tue, 09 Apr 2019 11:20:35 -0700 (PDT) Subject: [pypy-commit] pypy jit-cleanup: Close branch jit-cleanup Message-ID: <5cace273.1c69fb81.9841a.e3a8@mx.google.com> Author: Ronan Lamy Branch: jit-cleanup Changeset: r96428:939eca77f896 Date: 2019-04-09 18:20 +0000 http://bitbucket.org/pypy/pypy/changeset/939eca77f896/ Log: Close branch jit-cleanup From pypy.commits at gmail.com Tue Apr 9 14:20:54 2019 From: pypy.commits at gmail.com (rlamy) Date: Tue, 09 Apr 2019 11:20:54 -0700 (PDT) Subject: [pypy-commit] pypy default: Merged in jit-cleanup (pull request #641) Message-ID: <5cace286.1c69fb81.3cd8.ff1c@mx.google.com> Author: Ronan Lamy Branch: Changeset: r96429:a896c0b75448 Date: 2019-04-09 18:20 +0000 http://bitbucket.org/pypy/pypy/changeset/a896c0b75448/ Log: Merged in jit-cleanup (pull request #641) Remove rpython.jit.metainterp.typesystem diff too long, truncating to 2000 out of 4551 lines diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -9,3 +9,6 @@ Fix typo +.. branch: jit-cleanup + +Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -13,7 +13,6 @@ from pypy.module.pypyjit.interp_jit import pypyjitdriver from pypy.module.pypyjit.hooks import pypy_hooks from rpython.jit.tool.oparser import parse -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.jit import JitDebugInfo, AsmInfo, Counters @@ -31,7 +30,7 @@ class MockSD(object): class cpu(object): - ts = llhelper + pass jitdrivers_sd = [MockJitDriverSD] diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -150,7 +150,6 @@ EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) - typesystem = 'lltype' namespace = locals().copy() class TestRegallocSimple(CustomBaseTestRegalloc): diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -9,6 +9,7 @@ from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.optimizeopt import intbounds from rpython.jit.metainterp.optimize import SpeculativeError +from rpython.jit.metainterp.support import ptr2int, int_signext from rpython.jit.codewriter import longlong, heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo @@ -36,7 +37,7 @@ # front-end will mutate them under our feet again. We also # need to make sure things get freed. _cache={} - + def mapping(box): if isinstance(box, Const) or box is None: return box @@ -136,7 +137,7 @@ if self._vtable is Ellipsis: self._vtable = heaptracker.get_vtable_for_gcstruct(self._runner, self.S) - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(self._vtable)) + return ptr2int(self._vtable) def is_immutable(self): return heaptracker.is_immutable_struct(self.S) @@ -208,7 +209,7 @@ class ArrayDescr(AbstractDescr): all_interiorfielddescrs = None - + def __init__(self, A, runner): self.A = self.OUTERA = A self._is_pure = A._immutable_field(None) @@ -322,7 +323,6 @@ class LLGraphCPU(model.AbstractCPU): - from rpython.jit.metainterp.typesystem import llhelper as ts supports_floats = True supports_longlong = r_uint is not r_ulonglong supports_singlefloats = True @@ -735,7 +735,7 @@ return rffi.LONGLONG else: raise NotImplementedError(size) - + def bh_gc_load_indexed_i(self, struct, index, scale, base_ofs, bytes): T = self._get_int_type_from_size(bytes) x = llop.gc_load_indexed(T, struct, index, scale, base_ofs) @@ -877,8 +877,7 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return heaptracker.adr2int(result_adr) + return ptr2int(struct.typeptr) # vector operations vector_arith_code = """ @@ -978,7 +977,7 @@ bh_vec_expand_i = _bh_vec_expand def bh_vec_int_signext(self, vx, ext, count): - return [heaptracker.int_signext(_vx, ext) for _vx in vx] + return [int_signext(_vx, ext) for _vx in vx] def build_load(func): def load(self, struct, offset, scale, disp, descr, _count): @@ -1089,7 +1088,7 @@ if box.datatype == INT: for i,a in enumerate(arg): if isinstance(a, bool): - arg[i] = int(a) + arg[i] = int(a) assert all([lltype.typeOf(a) == lltype.Signed for a in arg]) elif box.datatype == FLOAT: assert all([lltype.typeOf(a) == longlong.FLOATSTORAGE or \ @@ -1552,13 +1551,12 @@ return res def execute_restore_exception(self, descr, kls, e): - kls = heaptracker.int2adr(kls) if e: value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, e) - assert llmemory.cast_ptr_to_adr(value.typeptr) == kls + assert ptr2int(value.typeptr) == kls lle = LLException(value.typeptr, e) else: - assert kls == llmemory.NULL + assert kls == 0 lle = None self.last_exception = lle diff --git a/rpython/jit/backend/llgraph/support.py b/rpython/jit/backend/llgraph/support.py --- a/rpython/jit/backend/llgraph/support.py +++ b/rpython/jit/backend/llgraph/support.py @@ -1,7 +1,6 @@ from rpython.jit.codewriter import longlong -from rpython.jit.codewriter import heaptracker - +from rpython.jit.metainterp.support import adr2int, ptr2int from rpython.jit.metainterp.history import getkind from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint @@ -20,9 +19,9 @@ def cast_to_int(x): TP = lltype.typeOf(x) if isinstance(TP, lltype.Ptr): - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + return ptr2int(x) if TP == llmemory.Address: - return heaptracker.adr2int(x) + return adr2int(x) if TP is lltype.SingleFloat: return longlong.singlefloat2int(x) return lltype.cast_primitive(lltype.Signed, x) @@ -82,7 +81,7 @@ return longlong.int2singlefloat(x) else: if lltype.typeOf(x) == llmemory.Address: - x = heaptracker.adr2int(x) + x = adr2int(x) return lltype.cast_primitive(TYPE, x) def cast_from_ptr(TYPE, x): diff --git a/rpython/jit/backend/llgraph/test/test_llgraph.py b/rpython/jit/backend/llgraph/test/test_llgraph.py --- a/rpython/jit/backend/llgraph/test/test_llgraph.py +++ b/rpython/jit/backend/llgraph/test/test_llgraph.py @@ -1,6 +1,4 @@ import py -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.jit.codewriter import heaptracker from rpython.jit.backend.test.runner_test import LLtypeBackendTest from rpython.jit.backend.llgraph.runner import LLGraphCPU @@ -17,16 +15,3 @@ def test_call_release_gil_variable_function_and_arguments(self): py.test.skip("the arguments seem not correctly casted") - - -def test_cast_adr_to_int_and_back(): - X = lltype.Struct('X', ('foo', lltype.Signed)) - x = lltype.malloc(X, immortal=True) - x.foo = 42 - a = llmemory.cast_ptr_to_adr(x) - i = heaptracker.adr2int(a) - assert lltype.typeOf(i) is lltype.Signed - a2 = heaptracker.int2adr(i) - assert llmemory.cast_adr_to_ptr(a2, lltype.Ptr(X)) == x - assert heaptracker.adr2int(llmemory.NULL) == 0 - assert heaptracker.int2adr(0) == llmemory.NULL diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py --- a/rpython/jit/backend/llsupport/descr.py +++ b/rpython/jit/backend/llsupport/descr.py @@ -4,6 +4,7 @@ from rpython.jit.backend.llsupport import symbolic, support from rpython.jit.metainterp.history import AbstractDescr, getkind, FLOAT, INT from rpython.jit.metainterp import history +from rpython.jit.metainterp.support import ptr2int, int2adr from rpython.jit.codewriter import heaptracker, longlong from rpython.jit.codewriter.longlong import is_longlong from rpython.jit.metainterp.optimizeopt import intbounds @@ -84,7 +85,7 @@ def is_valid_class_for(self, struct): objptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) cls = llmemory.cast_adr_to_ptr( - heaptracker.int2adr(self.get_vtable()), + int2adr(self.get_vtable()), lltype.Ptr(rclass.OBJECT_VTABLE)) # this first comparison is necessary, since we want to make sure # that vtable for JitVirtualRef is the same without actually reading @@ -95,7 +96,7 @@ return self.immutable_flag def get_vtable(self): - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(self.vtable)) + return ptr2int(self.vtable) def get_type_id(self): assert self.tid diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -11,6 +11,7 @@ from rpython.jit.codewriter import heaptracker from rpython.jit.metainterp.history import ConstPtr, AbstractDescr, ConstInt from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.metainterp.support import ptr2int from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr, FieldDescr @@ -66,7 +67,7 @@ @specialize.arg(1) def get_malloc_fn_addr(self, funcname): ll_func = self.get_malloc_fn(funcname) - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(ll_func)) + return ptr2int(ll_func) def _freeze_(self): return True diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -8,7 +8,8 @@ from rpython.rlib.objectmodel import we_are_translated, specialize, compute_hash from rpython.jit.metainterp import history, compile from rpython.jit.metainterp.optimize import SpeculativeError -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.metainterp.support import adr2int, ptr2int +from rpython.jit.codewriter import longlong from rpython.jit.backend.model import AbstractCPU from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes @@ -23,8 +24,6 @@ class AbstractLLCPU(AbstractCPU): - from rpython.jit.metainterp.typesystem import llhelper as ts - HAS_CODEMAP = False done_with_this_frame_descr_int = None # overridden by pyjitpl.py @@ -160,7 +159,7 @@ graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() - self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + self.realloc_frame = ptr2int(fptr) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame_crash) @@ -172,7 +171,7 @@ graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() - self.realloc_frame_crash = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) + self.realloc_frame_crash = ptr2int(fptr) def _setup_exception_handling_untranslated(self): # for running un-translated only, all exceptions occurring in the @@ -209,11 +208,11 @@ def pos_exception(): addr = llop.get_exception_addr(llmemory.Address) - return heaptracker.adr2int(addr) + return adr2int(addr) def pos_exc_value(): addr = llop.get_exc_value_addr(llmemory.Address) - return heaptracker.adr2int(addr) + return adr2int(addr) from rpython.rlib import rstack @@ -776,8 +775,7 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return heaptracker.adr2int(result_adr) + return ptr2int(struct.typeptr) def bh_new_array(self, length, arraydescr): return self.gc_ll_descr.gc_malloc_array(length, arraydescr) 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 @@ -1,18 +1,15 @@ from rpython.rlib import rgc -from rpython.rlib.objectmodel import we_are_translated, r_dict, always_inline +from rpython.rlib.objectmodel import we_are_translated, always_inline from rpython.rlib.rarithmetic import ovfcheck, highest_bit from rpython.rtyper.lltypesystem import llmemory, lltype, rstr from rpython.rtyper.annlowlevel import cast_instance_to_gcref -from rpython.jit.metainterp import history -from rpython.jit.metainterp.history import ConstInt, ConstPtr +from rpython.jit.metainterp.history import ( + ConstInt, ConstPtr, JitCellToken, new_ref_dict) from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers -from rpython.jit.metainterp.typesystem import rd_eq, rd_hash -from rpython.jit.codewriter import heaptracker +from rpython.jit.metainterp.support import ptr2int from rpython.jit.backend.llsupport.symbolic import (WORD, get_field_token, get_array_token) -from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr,\ - FLAG_POINTER -from rpython.jit.metainterp.history import JitCellToken +from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr from rpython.jit.backend.llsupport.descr import (unpack_arraydescr, unpack_fielddescr, unpack_interiorfielddescr) from rpython.rtyper.lltypesystem.lloperation import llop @@ -608,12 +605,10 @@ def handle_call_assembler(self, op): descrs = self.gc_ll_descr.getframedescrs(self.cpu) loop_token = op.getdescr() - assert isinstance(loop_token, history.JitCellToken) - jfi = loop_token.compiled_loop_token.frame_info - llfi = heaptracker.adr2int(llmemory.cast_ptr_to_adr(jfi)) + assert isinstance(loop_token, JitCellToken) + llfi = ptr2int(loop_token.compiled_loop_token.frame_info) frame = self.gen_malloc_frame(llfi) - self.emit_setfield(frame, history.ConstInt(llfi), - descr=descrs.jf_frame_info) + self.emit_setfield(frame, ConstInt(llfi), descr=descrs.jf_frame_info) arglist = op.getarglist() index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): @@ -948,7 +943,7 @@ def _gcref_index(self, gcref): if self.gcrefs_map is None: - self.gcrefs_map = r_dict(rd_eq, rd_hash) + self.gcrefs_map = new_ref_dict() try: return self.gcrefs_map[gcref] except KeyError: diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -1,6 +1,9 @@ import weakref from rpython.rlib.debug import debug_start, debug_print, debug_stop from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.rclass import OBJECTPTR +from rpython.jit.metainterp.history import ConstInt +from rpython.jit.metainterp.support import ptr2int class CPUTotalTracker(object): total_compiled_loops = 0 @@ -192,6 +195,10 @@ x = llmemory.cast_int_to_adr(x) return llmemory.cast_adr_to_ptr(x, TYPE) + def cls_of_box(self, box): + obj = lltype.cast_opaque_ptr(OBJECTPTR, box.getref_base()) + return ConstInt(ptr2int(obj.typeptr)) + # ---------- the backend-dependent operations ---------- diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -2,11 +2,12 @@ from rpython.jit.metainterp.history import BasicFinalDescr,\ JitCellToken, ConstInt, ConstFloat from rpython.jit.metainterp.resoperation import rop, InputArgInt, InputArgFloat +from rpython.jit.metainterp.support import ptr2int from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.backend.detect_cpu import getcpuclass from rpython.jit.backend.test.runner_test import Runner import py @@ -49,8 +50,7 @@ @classmethod def get_funcbox(cls, cpu, func_ptr): - addr = llmemory.cast_ptr_to_adr(func_ptr) - return ConstInt(heaptracker.adr2int(addr)) + return ConstInt(ptr2int(func_ptr)) def test_call_aligned_with_spilled_values(self): cpu = self.cpu diff --git a/rpython/jit/backend/test/jitlog_test.py b/rpython/jit/backend/test/jitlog_test.py --- a/rpython/jit/backend/test/jitlog_test.py +++ b/rpython/jit/backend/test/jitlog_test.py @@ -1,19 +1,8 @@ -import re import os -from rpython.rlib import debug -from rpython.jit.tool.oparser import pure_parse -from rpython.jit.metainterp import logger -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.rjitlog import rjitlog as jl -from StringIO import StringIO -from rpython.jit.metainterp.optimizeopt.util import equaloplists -from rpython.jit.metainterp.history import AbstractDescr, JitCellToken, BasicFailDescr, BasicFinalDescr -from rpython.jit.backend.model import AbstractCPU from rpython.rlib.jit import JitDriver -from rpython.rlib.objectmodel import always_inline from rpython.jit.metainterp.test.support import LLJitMixin from rpython.rlib.rjitlog import rjitlog -import tempfile class LoggerTest(LLJitMixin): @@ -34,7 +23,7 @@ file = tmpdir.join('jitlog') monkeypatch.setenv("JITLOG", file.strpath) f = self.run_sample_loop(None) - self.meta_interp(f, [10,0]) + self.meta_interp(f, [10, 0]) assert os.path.exists(file.strpath) with file.open('rb') as fd: # check the file header @@ -46,28 +35,16 @@ monkeypatch.setattr(jl, 'JITLOG_VERSION_16BIT_LE', '\xff\xfe') monkeypatch.setenv("JITLOG", file.strpath) f = self.run_sample_loop(None) - self.meta_interp(f, [10,0]) + self.meta_interp(f, [10, 0]) assert os.path.exists(file.strpath) with file.open('rb') as fd: # check the file header assert fd.read(3) == jl.MARK_JITLOG_HEADER + '\xff\xfe' assert len(fd.read()) > 0 - def test_version(self, monkeypatch, tmpdir): - file = tmpdir.join('jitlog') - monkeypatch.setattr(jl, 'JITLOG_VERSION_16BIT_LE', '\xff\xfe') - monkeypatch.setenv("JITLOG", file.strpath) - f = self.run_sample_loop(None) - self.meta_interp(f, [10,0]) - assert os.path.exists(file.strpath) - with file.open('rb') as fd: - # check the file header - assert fd.read(3) == jl.MARK_JITLOG_HEADER + '\xff\xfe' - assert len(fd.read()) > 0 - - def run_sample_loop(self, func, myjitdriver = None): + def run_sample_loop(self, func, myjitdriver=None): if not myjitdriver: - myjitdriver = JitDriver(greens = [], reds = 'auto') + myjitdriver = JitDriver(greens=[], reds='auto') def f(y, x): res = 0 if func: diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -1,22 +1,24 @@ -import py, sys, random, os, struct, operator, math -from rpython.jit.metainterp.history import (AbstractFailDescr, - AbstractDescr, - BasicFailDescr, - BasicFinalDescr, - JitCellToken, TargetToken, - ConstInt, ConstPtr, - ConstFloat, Const) -from rpython.jit.metainterp.resoperation import ResOperation, rop, InputArgInt,\ - InputArgFloat, opname, InputArgRef -from rpython.jit.metainterp.typesystem import deref +import py +import sys +import random +import os +import struct +import operator +import math +from rpython.jit.metainterp.history import ( + AbstractFailDescr, AbstractDescr, BasicFailDescr, BasicFinalDescr, + JitCellToken, TargetToken, ConstInt, ConstPtr, ConstFloat, Const) +from rpython.jit.metainterp.resoperation import ( + ResOperation, rop, InputArgInt, InputArgFloat, InputArgRef) from rpython.jit.metainterp.executor import wrap_constant +from rpython.jit.metainterp.support import ptr2int, int_signext from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi from rpython.rtyper import rclass from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.llinterp import LLException -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.rlib import longlong2float from rpython.rlib.rarithmetic import intmask, is_valid_int from rpython.jit.backend.detect_cpu import autodetect @@ -55,7 +57,7 @@ add_loop_instructions = ['overload for a specific cpu'] bridge_loop_instructions = ['overload for a specific cpu'] - + def execute_operation(self, opname, valueboxes, result_type, descr=None): inputargs, operations = self._get_single_operation_list(opname, result_type, @@ -506,7 +508,7 @@ return chr(ord(c) + 1) FPTR = self.Ptr(self.FuncType([lltype.Char], lltype.Char)) func_ptr = llhelper(FPTR, func) - calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char, + calldescr = cpu.calldescrof(FPTR.TO, (lltype.Char,), lltype.Char, EffectInfo.MOST_GENERAL) x = cpu.bh_call_i(self.get_funcbox(cpu, func_ptr).value, [ord('A')], None, None, calldescr) @@ -519,7 +521,7 @@ FPTR = self.Ptr(self.FuncType([lltype.Float, lltype.Signed], lltype.Float)) func_ptr = llhelper(FPTR, func) - FTP = deref(FPTR) + FTP = FPTR.TO calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT, EffectInfo.MOST_GENERAL) x = cpu.bh_call_f(self.get_funcbox(cpu, func_ptr).value, @@ -548,7 +550,7 @@ # FPTR = self.Ptr(self.FuncType([TP, TP], TP)) func_ptr = llhelper(FPTR, func) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcbox = self.get_funcbox(cpu, func_ptr) # first, try it with the "normal" calldescr calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -630,7 +632,7 @@ TP = lltype.Signed FPTR = self.Ptr(self.FuncType([TP, TP], TP)) func_ptr = llhelper(FPTR, f) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcconst = self.get_funcbox(self.cpu, func_ptr) funcbox = InputArgInt(funcconst.getint()) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -656,7 +658,7 @@ # FPTR = self.Ptr(self.FuncType([TP] * nb_args, TP)) func_ptr = llhelper(FPTR, func_ints) - FUNC = deref(FPTR) + FUNC = FPTR.TO calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) @@ -1820,7 +1822,7 @@ EffectInfo.OS_MATH_READ_TIMESTAMP) FPTR = self.Ptr(self.FuncType([], lltype.SignedLongLong)) func_ptr = llhelper(FPTR, rtimer.read_timestamp) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcbox = self.get_funcbox(self.cpu, func_ptr) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo) @@ -1844,8 +1846,7 @@ @classmethod def get_funcbox(cls, cpu, func_ptr): - addr = llmemory.cast_ptr_to_adr(func_ptr) - return ConstInt(heaptracker.adr2int(addr)) + return ConstInt(ptr2int(func_ptr)) MY_VTABLE = rclass.OBJECT_VTABLE # for tests only @@ -1867,7 +1868,6 @@ def alloc_instance(self, T): if hasattr(T, 'parent'): vtable_for_T = lltype.malloc(self.MY_VTABLE, immortal=True) - vtable_for_T_addr = llmemory.cast_ptr_to_adr(vtable_for_T) else: vtable_for_T = lltype.nullptr(rclass.OBJECT_VTABLE) cpu = self.cpu @@ -1896,7 +1896,7 @@ T_box = None else: vtable = vtable_for_T - T_box = ConstInt(heaptracker.adr2int(vtable_for_T_addr)) + T_box = ConstInt(ptr2int(vtable_for_T)) descr = cpu.sizeof(T, vtable) return t_box, T_box, descr @@ -1985,7 +1985,7 @@ def test_ooops_non_gc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') - v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + v = ptr2int(x) r = self.execute_operation(rop.PTR_EQ, [InputArgInt(v), InputArgInt(v)], 'int') assert r == 1 r = self.execute_operation(rop.PTR_NE, [InputArgInt(v), InputArgInt(v)], 'int') @@ -2777,8 +2777,7 @@ lltype.free(buffer, flavor='raw') cpu = self.cpu - func_adr = llmemory.cast_ptr_to_adr(c_GetCurrentDir.funcsym) - funcbox = ConstInt(heaptracker.adr2int(func_adr)) + funcbox = ConstInt(ptr2int(c_GetCurrentDir.funcsym)) calldescr = cpu._calldescr_dynamic_for_tests( [types.ulong, types.pointer], types.ulong, @@ -3617,14 +3616,10 @@ descrfld_rx = cpu.fielddescrof(RS, 'x') rs = lltype.malloc(RS, immortal=True) rs.x = '?' - x = cpu.bh_getfield_raw_i( - heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), - descrfld_rx) + x = cpu.bh_getfield_raw_i(ptr2int(rs), descrfld_rx) assert x == ord('?') # - cpu.bh_setfield_raw_i( - heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), - ord('!'), descrfld_rx) + cpu.bh_setfield_raw_i(ptr2int(rs), ord('!'), descrfld_rx) assert rs.x == '!' # @@ -3698,7 +3693,7 @@ def test_guards_nongc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') - v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + v = ptr2int(x) vbox = InputArgInt(v) ops = [ (rop.GUARD_NONNULL, vbox, False), @@ -3905,8 +3900,7 @@ descr = self.cpu.arraydescrof(ARRAY) a = lltype.malloc(ARRAY, 10, flavor='raw') a[7] = -4242 - addr = llmemory.cast_ptr_to_adr(a) - abox = InputArgInt(heaptracker.adr2int(addr)) + abox = InputArgInt(ptr2int(a)) r1 = self.execute_operation(rop.GETARRAYITEM_RAW_I, [abox, InputArgInt(7)], 'int', descr=descr) assert r1 == -4242 @@ -3916,8 +3910,7 @@ ARRAY = rffi.CArray(lltype.Signed) descr = self.cpu.arraydescrof(ARRAY) a = lltype.malloc(ARRAY, 10, flavor='raw') - addr = llmemory.cast_ptr_to_adr(a) - abox = InputArgInt(heaptracker.adr2int(addr)) + abox = InputArgInt(ptr2int(a)) self.execute_operation(rop.SETARRAYITEM_RAW, [abox, InputArgInt(5), InputArgInt(12345)], 'void', descr=descr) @@ -4191,7 +4184,7 @@ value = intmask(0xFFEEDDCCBBAA9988) expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) - a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) + a_rawint = ptr2int(a) x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) @@ -4212,7 +4205,7 @@ value = intmask(0xFFEEDDCCBBAA9988) expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) - a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) + a_rawint = ptr2int(a) res = self.execute_operation(rop.GETARRAYITEM_RAW_I, [InputArgInt(a_rawint), InputArgInt(3)], 'int', descr=descrarray) @@ -4454,7 +4447,7 @@ effectinfo = EffectInfo([], [], [], [], [], [], EffectInfo.EF_CANNOT_RAISE, EffectInfo.OS_MATH_SQRT) FPTR = self.Ptr(self.FuncType([lltype.Float], lltype.Float)) func_ptr = llhelper(FPTR, math_sqrt) - FUNC = deref(FPTR) + FUNC = FPTR.TO funcbox = self.get_funcbox(self.cpu, func_ptr) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo) @@ -4546,7 +4539,7 @@ for test_case in test_cases: deadframe = self.cpu.execute_token(looptoken, test_case) got = self.cpu.get_int_value(deadframe, 0) - expected = heaptracker.int_signext(test_case, numbytes) + expected = int_signext(test_case, numbytes) assert got == expected def test_compile_asmlen(self): @@ -4641,12 +4634,12 @@ assert a + 12 == g assert a + 14 == h assert a + 16 == i - FPTR = self.Ptr(self.FuncType([lltype.Signed]*9, lltype.Void)) + FPTR = self.Ptr(self.FuncType([lltype.Signed] * 9, lltype.Void)) func_ptr = llhelper(FPTR, func) cpu = self.cpu - calldescr = cpu.calldescrof(deref(FPTR), (lltype.Signed,)*9, lltype.Void, + calldescr = cpu.calldescrof(FPTR.TO, (lltype.Signed,) * 9, lltype.Void, EffectInfo.MOST_GENERAL) - faildescr=BasicFailDescr(42) + faildescr = BasicFailDescr(42) loop = parse(""" [i0] label(i0, descr=targettoken1) @@ -5067,8 +5060,7 @@ a = lltype.malloc(A, 2, flavor='raw') a[0] = rffi.cast(rffi.SHORT, 666) a[1] = rffi.cast(rffi.SHORT, 777) - addr = llmemory.cast_ptr_to_adr(a) - a_int = heaptracker.adr2int(addr) + a_int = ptr2int(a) print 'a_int:', a_int self.execute_operation(rop.SETARRAYITEM_RAW, [ConstInt(a_int), ConstInt(0), ConstInt(-7654)], @@ -5102,8 +5094,7 @@ A = lltype.GcArray(OF) arraydescr = self.cpu.arraydescrof(A) a = lltype.malloc(A, 100) - addr = llmemory.cast_ptr_to_adr(a) - a_int = heaptracker.adr2int(addr) + a_int = ptr2int(a) a_ref = lltype.cast_opaque_ptr(llmemory.GCREF, a) for (start, length) in [(0, 100), (49, 49), (1, 98), (15, 9), (10, 10), (47, 0), @@ -5258,7 +5249,7 @@ xptr = lltype.malloc(X) xptr.parent.typeptr = xtp x_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, xptr)) - X_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(xtp))) + X_box = ConstInt(ptr2int(xtp)) ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) ytp.subclassrange_min = 2 @@ -5269,7 +5260,7 @@ yptr = lltype.malloc(Y) yptr.parent.parent.typeptr = ytp y_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, yptr)) - Y_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(ytp))) + Y_box = ConstInt(ptr2int(ytp)) ztp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) ztp.subclassrange_min = 4 @@ -5281,7 +5272,7 @@ zptr = lltype.malloc(Z) zptr.parent.typeptr = ztp z_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, zptr)) - Z_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(ztp))) + Z_box = ConstInt(ptr2int(ztp)) for num, arg, klass, is_subclass in [ (1, x_box, X_box, True), diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py --- a/rpython/jit/backend/test/test_ll_random.py +++ b/rpython/jit/backend/test/test_ll_random.py @@ -5,6 +5,7 @@ from rpython.jit.backend.test.test_random import getint, getref_base, getref from rpython.jit.metainterp.resoperation import ResOperation, rop, optypes from rpython.jit.metainterp.history import ConstInt, ConstPtr, getkind +from rpython.jit.metainterp.support import ptr2int from rpython.jit.codewriter import heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rtyper.annlowlevel import llhelper @@ -218,9 +219,6 @@ # ____________________________________________________________ -def ConstAddr(addr, cpu): - return ConstInt(heaptracker.adr2int(addr)) - class GuardClassOperation(test_random.GuardOperation): def gen_guard(self, builder, r): ptrvars = [(v, S) for (v, S) in builder.ptrvars @@ -235,7 +233,7 @@ v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable = S._hints['vtable']._as_ptr() vtable2 = S2._hints['vtable']._as_ptr() - c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), builder.cpu) + c_vtable2 = ConstInt(ptr2int(vtable2)) op = ResOperation(self.opnum, [v, c_vtable2], None) return op, (vtable == vtable2) @@ -249,8 +247,7 @@ builder.loop.operations.append(op) v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable2 = S2._hints['vtable']._as_ptr() - c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), - builder.cpu) + c_vtable2 = ConstInt(ptr2int(vtable2)) op = ResOperation(self.opnum, [op, c_vtable2], None) return op, False @@ -571,7 +568,7 @@ sum = %s return %s """ % (funcargs, sum, result)).compile() - d = {'intmask' : intmask} + d = {'intmask': intmask} exec code in d return subset, d['f'] @@ -587,8 +584,8 @@ vtableptr = v._hints['vtable']._as_ptr() d = { 'ptr': getref_base(S), - 'vtable' : vtableptr, - 'LLException' : LLException, + 'vtable': vtableptr, + 'LLException': LLException, } exec code in d return subset, d['f'], vtableptr @@ -616,7 +613,7 @@ RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) @@ -633,12 +630,12 @@ RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) - exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) + exc_box = ConstInt(ptr2int(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(builder.subset_of_intvars(r)) @@ -655,11 +652,11 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) - exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) + exc_box = ConstInt(ptr2int(exc)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(fail_subset) @@ -672,13 +669,13 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) - op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) + op._exc_box = ConstInt(ptr2int(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op @@ -691,7 +688,7 @@ subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) @@ -699,10 +696,10 @@ _, vtableptr = builder.get_random_structure_type_and_vtable(r) if vtableptr != exc: break - other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) + other_box = ConstInt(ptr2int(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], descr=builder.getfaildescr()) - op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) + op._exc_box = ConstInt(ptr2int(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op @@ -735,7 +732,7 @@ # TP = lltype.FuncType([lltype.Signed] * len(subset), RESULT_TYPE) ptr = llhelper(lltype.Ptr(TP), call_me) - c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) + c_addr = ConstInt(ptr2int(ptr)) args = [v_cond, c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) diff --git a/rpython/jit/codewriter/assembler.py b/rpython/jit/codewriter/assembler.py --- a/rpython/jit/codewriter/assembler.py +++ b/rpython/jit/codewriter/assembler.py @@ -1,9 +1,10 @@ from rpython.jit.metainterp.history import AbstractDescr, getkind +from rpython.jit.metainterp.support import adr2int, int2adr from rpython.jit.codewriter.flatten import Register, Label, TLabel, KINDS from rpython.jit.codewriter.flatten import ListOfKind, IndirectCallTargets from rpython.jit.codewriter.format import format_assembler from rpython.jit.codewriter.jitcode import SwitchDictDescr, JitCode -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.rlib.objectmodel import ComputedIntSymbolic from rpython.rlib.rarithmetic import r_int from rpython.flowspace.model import Constant @@ -77,7 +78,7 @@ value = llmemory.cast_ptr_to_adr(value) TYPE = llmemory.Address if TYPE == llmemory.Address: - value = heaptracker.adr2int(value) + value = adr2int(value) if TYPE is lltype.SingleFloat: value = longlong.singlefloat2int(value) if not isinstance(value, (llmemory.AddressAsInt, @@ -265,7 +266,7 @@ # Helper called at the end of assembling. Registers the extra # functions shown in _callinfo_for_oopspec. for func in callinfocollection.all_function_addresses_as_int(): - func = heaptracker.int2adr(func) + func = int2adr(func) self.see_raw_object(func.ptr) diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py --- a/rpython/jit/codewriter/effectinfo.py +++ b/rpython/jit/codewriter/effectinfo.py @@ -1,9 +1,9 @@ import sys -from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem from rpython.rtyper.rclass import OBJECT from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.translator.backendopt.graphanalyze import BoolGraphAnalyzer from rpython.tool.algo import bitstring +from rpython.jit.metainterp.support import int2adr class UnsupportedFieldExc(Exception): @@ -298,19 +298,19 @@ write_descrs_interiorfields = [] def add_struct(descrs_fields, (_, T, fieldname)): - T = deref(T) + T = T.TO if consider_struct(T, fieldname): descr = cpu.fielddescrof(T, fieldname) descrs_fields.append(descr) def add_array(descrs_arrays, (_, T)): - ARRAY = deref(T) + ARRAY = T.TO if consider_array(ARRAY): descr = cpu.arraydescrof(ARRAY) descrs_arrays.append(descr) def add_interiorfield(descrs_interiorfields, (_, T, fieldname)): - T = deref(T) + T = T.TO if not isinstance(T, lltype.Array): return # let's not consider structs for now if not consider_array(T): @@ -329,7 +329,7 @@ extraef = list() for tup in effects: if tup[0] == "interiorfield" or tup[0] == "readinteriorfield": - T = deref(tup[1]) + T = tup[1].TO if isinstance(T, lltype.Array) and consider_array(T): val = (tup[0].replace("interiorfield", "array"), tup[1]) @@ -377,7 +377,7 @@ can_collect) def consider_struct(TYPE, fieldname): - if fieldType(TYPE, fieldname) is lltype.Void: + if getattr(TYPE, fieldname) is lltype.Void: return False if not isinstance(TYPE, lltype.GcStruct): # can be a non-GC-struct return False @@ -389,7 +389,7 @@ return True def consider_array(ARRAY): - if arrayItem(ARRAY) is lltype.Void: + if ARRAY.OF is lltype.Void: return False if not isinstance(ARRAY, lltype.GcArray): # can be a non-GC-array return False @@ -446,9 +446,8 @@ return (None, 0) def _funcptr_for_oopspec_memo(self, oopspecindex): - from rpython.jit.codewriter import heaptracker _, func_as_int = self.callinfo_for_oopspec(oopspecindex) - funcadr = heaptracker.int2adr(func_as_int) + funcadr = int2adr(func_as_int) return funcadr.ptr _funcptr_for_oopspec_memo._annspecialcase_ = 'specialize:memo' diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py --- a/rpython/jit/codewriter/heaptracker.py +++ b/rpython/jit/codewriter/heaptracker.py @@ -1,30 +1,9 @@ -from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper import rclass -from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.rarithmetic import r_uint, intmask - - -def adr2int(addr): - # Cast an address to an int. Returns an AddressAsInt object which - # can be cast back to an address. - return llmemory.cast_adr_to_int(addr, "symbolic") - -def int2adr(int): - return llmemory.cast_int_to_adr(int) - -def int_signext(value, numbytes): - b8 = numbytes * 8 - a = r_uint(value) - a += r_uint(1 << (b8 - 1)) # a += 128 - a &= r_uint((1 << b8) - 1) # a &= 255 - a -= r_uint(1 << (b8 - 1)) # a -= 128 - return intmask(a) def is_immutable_struct(S): return isinstance(S, lltype.GcStruct) and S._hints.get('immutable', False) -# ____________________________________________________________ - def has_gcstruct_a_vtable(GCSTRUCT): if not isinstance(GCSTRUCT, lltype.GcStruct): return False @@ -132,4 +111,3 @@ return cur_index cur_index += 1 return -cur_index - 1 # not found - diff --git a/rpython/jit/codewriter/jitcode.py b/rpython/jit/codewriter/jitcode.py --- a/rpython/jit/codewriter/jitcode.py +++ b/rpython/jit/codewriter/jitcode.py @@ -1,5 +1,5 @@ from rpython.jit.metainterp.history import AbstractDescr, ConstInt -from rpython.jit.codewriter import heaptracker +from rpython.jit.metainterp.support import adr2int from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import base_int @@ -8,7 +8,7 @@ _empty_i = [] _empty_r = [] _empty_f = [] - + def __init__(self, name, fnaddr=None, calldescr=None, called_from=None): self.name = name self.fnaddr = fnaddr @@ -41,7 +41,7 @@ self._resulttypes = resulttypes # debugging def get_fnaddr_as_int(self): - return heaptracker.adr2int(self.fnaddr) + return adr2int(self.fnaddr) def num_regs_i(self): return ord(self.c_num_regs_i) diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -6,10 +6,9 @@ from rpython.jit.codewriter.policy import log from rpython.jit.metainterp import quasiimmut from rpython.jit.metainterp.history import getkind -from rpython.jit.metainterp.typesystem import deref, arrayItem from rpython.jit.metainterp.blackhole import BlackholeInterpreter -from rpython.flowspace.model import SpaceOperation, Variable, Constant,\ - c_last_exception +from rpython.jit.metainterp.support import ptr2int +from rpython.flowspace.model import SpaceOperation, Variable, Constant from rpython.rlib import objectmodel from rpython.rlib.jit import _we_are_jitted from rpython.rlib.rgc import lltype_is_gc @@ -1729,9 +1728,9 @@ (in which case the original call is written as a residual call). """ if oopspec_name.startswith('new'): - LIST = deref(op.result.concretetype) + LIST = op.result.concretetype.TO else: - LIST = deref(args[0].concretetype) + LIST = args[0].concretetype.TO resizable = isinstance(LIST, lltype.GcStruct) assert resizable == (not isinstance(LIST, lltype.GcArray)) if resizable: @@ -1956,8 +1955,7 @@ if isinstance(op.args[0].value, str): pass # for tests only else: - func = heaptracker.adr2int( - llmemory.cast_ptr_to_adr(op.args[0].value)) + func = ptr2int(op.args[0].value) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) op1 = self.rewrite_call(op, 'residual_call', @@ -1984,8 +1982,7 @@ if isinstance(c_func.value, str): # in tests only func = c_func.value else: - func = heaptracker.adr2int( - llmemory.cast_ptr_to_adr(c_func.value)) + func = ptr2int(c_func.value) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) def _handle_int_special(self, op, oopspec_name, args): diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py --- a/rpython/jit/codewriter/support.py +++ b/rpython/jit/codewriter/support.py @@ -4,7 +4,6 @@ from rpython.rtyper.llannotation import lltype_to_annotation from rpython.annotator.policy import AnnotatorPolicy from rpython.flowspace.model import Variable, Constant -from rpython.jit.metainterp.typesystem import deref from rpython.rlib import rgc from rpython.rlib.jit import elidable, oopspec from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask @@ -142,7 +141,7 @@ assert len(lst) == len(args_v), ( "not supported so far: 'greens' variables contain Void") # a crash here means that you have to reorder the variable named in - # the JitDriver. + # the JitDriver. lst2 = sort_vars(lst) assert lst == lst2, ("You have to reorder the variables named in " "the JitDriver (both the 'greens' and 'reds' independently). " @@ -786,7 +785,7 @@ bk = rtyper.annotator.bookkeeper ll_restype = ll_res if impl.need_result_type != 'exact': - ll_restype = deref(ll_restype) + ll_restype = ll_restype.TO desc = bk.getdesc(ll_restype) else: class TestingDesc(object): diff --git a/rpython/jit/codewriter/test/test_assembler.py b/rpython/jit/codewriter/test/test_assembler.py --- a/rpython/jit/codewriter/test/test_assembler.py +++ b/rpython/jit/codewriter/test/test_assembler.py @@ -3,8 +3,9 @@ from rpython.jit.codewriter.flatten import SSARepr, Label, TLabel, Register from rpython.jit.codewriter.flatten import ListOfKind, IndirectCallTargets from rpython.jit.codewriter.jitcode import MissingLiveness -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.metainterp.history import AbstractDescr +from rpython.jit.metainterp.support import ptr2int from rpython.flowspace.model import Constant from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rlib.rarithmetic import r_int, r_uint @@ -106,7 +107,7 @@ assert assembler.insns == {'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2} - f_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(f)) + f_int = ptr2int(f) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert jitcode.constants_r == [s_gcref] diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py --- a/rpython/jit/codewriter/test/test_flatten.py +++ b/rpython/jit/codewriter/test/test_flatten.py @@ -1,12 +1,12 @@ import py, sys from rpython.jit.codewriter import support -from rpython.jit.codewriter.heaptracker import int_signext from rpython.jit.codewriter.flatten import flatten_graph, reorder_renaming_list from rpython.jit.codewriter.flatten import GraphFlattener, ListOfKind, Register from rpython.jit.codewriter.format import assert_format from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.history import AbstractDescr +from rpython.jit.metainterp.support import int_signext from rpython.rtyper.lltypesystem import lltype, rstr, rffi from rpython.rtyper import rclass from rpython.flowspace.model import SpaceOperation, Variable, Constant diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -12,6 +12,7 @@ from rpython.jit.codewriter import heaptracker, effectinfo from rpython.jit.codewriter.flatten import ListOfKind from rpython.jit.codewriter.jtransform import Transformer, UnsupportedMallocFlags +from rpython.jit.metainterp.support import int2adr from rpython.jit.metainterp.history import getkind def const(x): @@ -1198,7 +1199,7 @@ got = cc.callinfocollection.seen[0] assert got[0] == effectinfo.EffectInfo.OS_UNI_CONCAT assert got[1] == op1.args[2] # the calldescr - assert heaptracker.int2adr(got[2]) == llmemory.cast_ptr_to_adr(func) + assert int2adr(got[2]) == llmemory.cast_ptr_to_adr(func) def test_str_slice(): # test that the oopspec is present and correctly transformed diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -1,9 +1,11 @@ -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.codewriter import longlong from rpython.jit.codewriter.jitcode import JitCode, SwitchDictDescr from rpython.jit.metainterp.compile import ResumeAtPositionDescr from rpython.jit.metainterp.jitexc import get_llexception, reraise from rpython.jit.metainterp import jitexc from rpython.jit.metainterp.history import MissingValue +from rpython.jit.metainterp.support import ( + adr2int, int2adr, ptr2int, int_signext) from rpython.rlib import longlong2float from rpython.rlib.debug import ll_assert, make_sure_not_resized from rpython.rlib.debug import check_annotation @@ -539,7 +541,7 @@ return i @arguments("i", "i", returns="i") def bhimpl_int_signext(a, b): - return heaptracker.int_signext(a, b) + return int_signext(a, b) @arguments("i", "i", returns="i") def bhimpl_uint_lt(a, b): @@ -930,7 +932,7 @@ @arguments("self", "i", "L", "pc", returns="L") def bhimpl_goto_if_exception_mismatch(self, vtable, target, pc): - adr = heaptracker.int2adr(vtable) + adr = int2adr(vtable) bounding_class = llmemory.cast_adr_to_ptr(adr, rclass.CLASSTYPE) real_instance = self.exception_last_value assert real_instance @@ -943,8 +945,7 @@ def bhimpl_last_exception(self): real_instance = self.exception_last_value assert real_instance - adr = llmemory.cast_ptr_to_adr(real_instance.typeptr) - return heaptracker.adr2int(adr) + return ptr2int(real_instance.typeptr) @arguments("self", returns="r") def bhimpl_last_exc_value(self): @@ -1050,7 +1051,7 @@ def get_portal_runner(self, jdindex): jitdriver_sd = self.builder.metainterp_sd.jitdrivers_sd[jdindex] - fnptr = heaptracker.adr2int(jitdriver_sd.portal_runner_adr) + fnptr = adr2int(jitdriver_sd.portal_runner_adr) calldescr = jitdriver_sd.mainjitcode.calldescr return fnptr, calldescr @@ -1233,45 +1234,45 @@ @arguments("cpu", "j", "R", returns="i") def bhimpl_inline_call_r_i(cpu, jitcode, args_r): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_i(adr2int(jitcode.fnaddr), None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "R", returns="r") def bhimpl_inline_call_r_r(cpu, jitcode, args_r): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_r(adr2int(jitcode.fnaddr), None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "R") def bhimpl_inline_call_r_v(cpu, jitcode, args_r): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_v(adr2int(jitcode.fnaddr), None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", returns="i") def bhimpl_inline_call_ir_i(cpu, jitcode, args_i, args_r): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_i(adr2int(jitcode.fnaddr), args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", returns="r") def bhimpl_inline_call_ir_r(cpu, jitcode, args_i, args_r): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_r(adr2int(jitcode.fnaddr), args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R") def bhimpl_inline_call_ir_v(cpu, jitcode, args_i, args_r): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_v(adr2int(jitcode.fnaddr), args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="i") def bhimpl_inline_call_irf_i(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_i(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="r") def bhimpl_inline_call_irf_r(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_r(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="f") def bhimpl_inline_call_irf_f(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_f(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_f(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F") def bhimpl_inline_call_irf_v(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + return cpu.bh_call_v(adr2int(jitcode.fnaddr), args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "i", "d", returns="r") @@ -1622,7 +1623,7 @@ elif kind == 'i': raise jitexc.DoneWithThisFrameInt(self.get_tmpreg_i()) elif kind == 'r': - raise jitexc.DoneWithThisFrameRef(self.cpu, self.get_tmpreg_r()) + raise jitexc.DoneWithThisFrameRef(self.get_tmpreg_r()) elif kind == 'f': raise jitexc.DoneWithThisFrameFloat(self.get_tmpreg_f()) else: @@ -1631,7 +1632,7 @@ def _exit_frame_with_exception(self, e): sd = self.builder.metainterp_sd e = lltype.cast_opaque_ptr(llmemory.GCREF, e) - raise jitexc.ExitFrameWithExceptionRef(self.cpu, e) + raise jitexc.ExitFrameWithExceptionRef(e) def _handle_jitexception_in_portal(self, e): # This case is really rare, but can occur if diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -1,6 +1,7 @@ import weakref from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.annlowlevel import cast_instance_to_gcref +from rpython.rtyper.annlowlevel import ( + cast_instance_to_gcref, cast_gcref_to_instance) from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.debug import debug_start, debug_stop, debug_print, have_debug_prints from rpython.rlib.rarithmetic import r_uint, intmask @@ -20,7 +21,8 @@ from rpython.jit.metainterp.resume import (PENDINGFIELDSP, ResumeDataDirectReader, AccumInfo) from rpython.jit.metainterp.resumecode import NUMBERING -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.metainterp.support import adr2int +from rpython.jit.codewriter import longlong def giveup(): @@ -654,6 +656,7 @@ class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr): def get_result(self, cpu, deadframe): return cpu.get_int_value(deadframe, 0) + def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert jitdriver_sd.result_type == history.INT cpu = metainterp_sd.cpu @@ -662,14 +665,16 @@ class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr): def get_result(self, cpu, deadframe): return cpu.get_ref_value(deadframe, 0) + def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert jitdriver_sd.result_type == history.REF cpu = metainterp_sd.cpu - raise jitexc.DoneWithThisFrameRef(cpu, self.get_result(cpu, deadframe)) + raise jitexc.DoneWithThisFrameRef(self.get_result(cpu, deadframe)) class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr): def get_result(self, cpu, deadframe): return cpu.get_float_value(deadframe, 0) + def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert jitdriver_sd.result_type == history.FLOAT cpu = metainterp_sd.cpu @@ -679,7 +684,7 @@ def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): cpu = metainterp_sd.cpu value = cpu.get_ref_value(deadframe, 0) - raise jitexc.ExitFrameWithExceptionRef(cpu, value) + raise jitexc.ExitFrameWithExceptionRef(value) def make_and_attach_done_descrs(targets): @@ -730,7 +735,7 @@ else: from rpython.jit.metainterp.blackhole import resume_in_blackhole if isinstance(self, ResumeGuardCopiedDescr): - resume_in_blackhole(metainterp_sd, jitdriver_sd, self.prev, deadframe) + resume_in_blackhole(metainterp_sd, jitdriver_sd, self.prev, deadframe) else: assert isinstance(self, ResumeGuardDescr) resume_in_blackhole(metainterp_sd, jitdriver_sd, self, deadframe) @@ -921,22 +926,19 @@ cloned.copy_all_attributes_from(self) return cloned -class AllVirtuals: +class AllVirtuals(object): llopaque = True cache = None def __init__(self, cache): self.cache = cache - def hide(self, cpu): - ptr = cpu.ts.cast_instance_to_base_ref(self) - return cpu.ts.cast_to_ref(ptr) + def hide(self): + return cast_instance_to_gcref(self) @staticmethod - def show(cpu, gcref): - from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance - ptr = cpu.ts.cast_to_baseclass(gcref) - return cast_base_ptr_to_instance(AllVirtuals, ptr) + def show(gcref): + return cast_gcref_to_instance(AllVirtuals, gcref) def invent_fail_descr_for_op(opnum, optimizer, copied_from_descr=None): if opnum == rop.GUARD_NOT_FORCED or opnum == rop.GUARD_NOT_FORCED_2: @@ -971,7 +973,7 @@ # handle_async_forcing() just a moment ago. from rpython.jit.metainterp.blackhole import resume_in_blackhole hidden_all_virtuals = metainterp_sd.cpu.get_savedata_ref(deadframe) - obj = AllVirtuals.show(metainterp_sd.cpu, hidden_all_virtuals) + obj = AllVirtuals.show(hidden_all_virtuals) all_virtuals = obj.cache if all_virtuals is None: all_virtuals = ResumeDataDirectReader.VirtualCache([], []) @@ -1014,8 +1016,7 @@ # Handle all_virtuals: keep them for later blackholing from the # future failure of the GUARD_NOT_FORCED obj = AllVirtuals(all_virtuals) - hidden_all_virtuals = obj.hide(metainterp_sd.cpu) - metainterp_sd.cpu.set_savedata_ref(deadframe, hidden_all_virtuals) + metainterp_sd.cpu.set_savedata_ref(deadframe, obj.hide()) class ResumeFromInterpDescr(ResumeDescr): def __init__(self, original_greenkey): @@ -1120,7 +1121,7 @@ if not exception: exception = cast_instance_to_gcref(memory_error) assert exception, "PropagateExceptionDescr: no exception??" - raise jitexc.ExitFrameWithExceptionRef(cpu, exception) + raise jitexc.ExitFrameWithExceptionRef(exception) def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): @@ -1147,7 +1148,7 @@ raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr - funcbox = history.ConstInt(heaptracker.adr2int(k)) + funcbox = history.ConstInt(adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # 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 @@ -1,8 +1,10 @@ import sys from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import we_are_translated, Symbolic -from rpython.rlib.objectmodel import compute_unique_id, specialize +from rpython.rtyper.annlowlevel import ( + cast_gcref_to_instance, cast_instance_to_gcref) +from rpython.rlib.objectmodel import ( + we_are_translated, Symbolic, compute_unique_id, specialize, r_dict) from rpython.rlib.rarithmetic import r_int64, is_valid_int from rpython.rlib.rarithmetic import LONG_BIT, intmask, r_uint from rpython.rlib.jit import Counters @@ -12,7 +14,8 @@ from rpython.jit.metainterp.resoperation import ResOperation, rop,\ AbstractValue, oparity, AbstractResOp, IntOp, RefOp, FloatOp,\ opclasses -from rpython.jit.codewriter import heaptracker, longlong +from rpython.jit.metainterp.support import ptr2int, int2adr +from rpython.jit.codewriter import longlong import weakref from rpython.jit.metainterp import jitexc @@ -97,14 +100,11 @@ return '%r' % (self,) def hide(self, cpu): - descr_ptr = cpu.ts.cast_instance_to_base_ref(self) - return cpu.ts.cast_to_ref(descr_ptr) + return cast_instance_to_gcref(self) @staticmethod def show(cpu, descr_gcref): - from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance - descr_ptr = cpu.ts.cast_to_baseclass(descr_gcref) - return cast_base_ptr_to_instance(AbstractDescr, descr_ptr) + return cast_gcref_to_instance(AbstractDescr, descr_gcref) def get_vinfo(self): raise NotImplementedError @@ -182,12 +182,10 @@ kind = getkind(T) if kind == "int": if isinstance(T, lltype.Ptr): - intval = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) + intval = ptr2int(x) else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) - elif kind == "ref": - return cpu.ts.new_ConstRef(x) elif kind == "float": return ConstFloat(longlong.getfloatstorage(x)) else: @@ -231,7 +229,7 @@ getvalue = getint def getaddr(self): - return heaptracker.int2adr(self.value) + return int2adr(self.value) def _get_hash_(self): return make_hashable_int(self.value) @@ -354,7 +352,7 @@ from rpython.rtyper.lltypesystem.ll2ctypes import NotCtypesAllocatedStructure if not we_are_translated() and isinstance(i, llmemory.AddressAsInt): # Warning: such a hash changes at the time of translation - adr = heaptracker.int2adr(i) + adr = int2adr(i) try: return llmemory.cast_adr_to_int(adr, "emulated") except NotCtypesAllocatedStructure: @@ -389,6 +387,20 @@ return result _const_ptr_for_unicode = {} +# A dict whose keys are refs (like the .value of ConstPtr). +# It is an r_dict. Note that NULL is not allowed as a key. + at specialize.call_location() +def new_ref_dict(): + return r_dict(rd_eq, rd_hash, simple_hash_eq=True) + +def rd_eq(ref1, ref2): + return ref1 == ref2 + +def rd_hash(ref): + assert ref + return lltype.identityhash(ref) + + # ____________________________________________________________ # The JitCellToken class is the root of a tree of traces. Each branch ends @@ -716,7 +728,7 @@ @specialize.argtype(2) def set_op_value(self, op, value): if value is None: - return + return elif isinstance(value, bool): op.setint(int(value)) elif lltype.typeOf(value) == lltype.Signed: diff --git a/rpython/jit/metainterp/jitexc.py b/rpython/jit/metainterp/jitexc.py --- a/rpython/jit/metainterp/jitexc.py +++ b/rpython/jit/metainterp/jitexc.py @@ -1,6 +1,6 @@ from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance -from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.rtyper.llinterp import LLException from rpython.rlib.objectmodel import we_are_translated @@ -22,13 +22,15 @@ def __init__(self, result): assert lltype.typeOf(result) is lltype.Signed self.result = result + def __str__(self): return 'DoneWithThisFrameInt(%s)' % (self.result,) class DoneWithThisFrameRef(JitException): - def __init__(self, cpu, result): - assert lltype.typeOf(result) == cpu.ts.BASETYPE + def __init__(self, result): + assert lltype.typeOf(result) == llmemory.GCREF self.result = result + def __str__(self): return 'DoneWithThisFrameRef(%s)' % (self.result,) @@ -36,13 +38,15 @@ def __init__(self, result): assert lltype.typeOf(result) is longlong.FLOATSTORAGE self.result = result + def __str__(self): return 'DoneWithThisFrameFloat(%s)' % (self.result,) class ExitFrameWithExceptionRef(JitException): - def __init__(self, cpu, value): - assert lltype.typeOf(value) == cpu.ts.BASETYPE + def __init__(self, value): + assert lltype.typeOf(value) == llmemory.GCREF self.value = value + def __str__(self): return 'ExitFrameWithExceptionRef(%s)' % (self.value,) diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py --- a/rpython/jit/metainterp/logger.py +++ b/rpython/jit/metainterp/logger.py @@ -1,4 +1,4 @@ -from rpython.jit.metainterp.history import ConstInt, ConstFloat +from rpython.jit.metainterp.history import ConstInt, ConstFloat, ConstPtr from rpython.jit.metainterp.resoperation import rop, AbstractInputArg from rpython.rlib.debug import (have_debug_prints, debug_start, debug_stop, debug_print) @@ -135,7 +135,6 @@ """ def __init__(self, metainterp_sd, guard_number, memo): self.metainterp_sd = metainterp_sd - self.ts = metainterp_sd.cpu.ts self.guard_number = guard_number if memo is None: memo = {} @@ -157,7 +156,7 @@ if name: return 'ConstClass(' + name + ')' return str(arg.value) - elif isinstance(arg, self.ts.ConstRef): + elif isinstance(arg, ConstPtr): if arg.value: return 'ConstPtr(ptr' + str(mv) + ')' return 'ConstPtr(null)' diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -6,14 +6,14 @@ Snapshot index for guards points to snapshot stored in _snapshots of trace """ -from rpython.jit.metainterp.history import ConstInt, Const, ConstFloat, ConstPtr +from rpython.jit.metainterp.history import ( + ConstInt, Const, ConstFloat, ConstPtr, new_ref_dict) from rpython.jit.metainterp.resoperation import AbstractResOp, AbstractInputArg,\ ResOperation, oparity, rop, opwithdescr, GuardResOp, IntOp, FloatOp, RefOp,\ opclasses from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.rtyper.lltypesystem import rffi, lltype, llmemory -from rpython.jit.metainterp.typesystem import llhelper TAGINT, TAGCONSTPTR, TAGCONSTOTHER, TAGBOX = range(4) TAGMASK = 0x3 @@ -179,7 +179,7 @@ if opwithdescr[opnum]: descr_index = self._next() if rop.is_guard(opnum): - update_liveranges(self.trace._snapshots[descr_index], index, + update_liveranges(self.trace._snapshots[descr_index], index, liveranges) if opclasses[opnum].type != 'v': return index + 1 @@ -274,7 +274,7 @@ self._consts_ptr = 0 self._descrs = [None] self._refs = [lltype.nullptr(llmemory.GCREF.TO)] - self._refs_dict = llhelper.new_ref_dict_3() + self._refs_dict = new_ref_dict() self._bigints = [] self._bigints_dict = {} self._floats = [] @@ -304,7 +304,7 @@ assert not self.tag_overflow self._bigints_dict = {} - self._refs_dict = llhelper.new_ref_dict_3() + self._refs_dict = new_ref_dict() debug_start("jit-trace-done") debug_print("trace length: " + str(self._pos)) debug_print(" total snapshots: " + str(self._total_snapshots)) diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py b/rpython/jit/metainterp/optimizeopt/bridgeopt.py --- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py +++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py @@ -2,6 +2,7 @@ optimizer of the bridge attached to a guard. """ from rpython.jit.metainterp import resumecode +from rpython.jit.metainterp.history import Const, ConstInt, CONST_NULL # adds the following sections at the end of the resume code: @@ -34,7 +35,6 @@ # maybe should be delegated to the optimization classes? def tag_box(box, liveboxes_from_env, memo): - from rpython.jit.metainterp.history import Const if isinstance(box, Const): return memo.getconst(box) else: @@ -43,13 +43,12 @@ def decode_box(resumestorage, tagged, liveboxes, cpu): from rpython.jit.metainterp.resume import untag, TAGCONST, TAGINT, TAGBOX from rpython.jit.metainterp.resume import NULLREF, TAG_CONST_OFFSET, tagged_eq - from rpython.jit.metainterp.history import ConstInt num, tag = untag(tagged) # NB: the TAGVIRTUAL case can't happen here, because this code runs after # virtuals are already forced again if tag == TAGCONST: if tagged_eq(tagged, NULLREF): - box = cpu.ts.CONST_NULL + box = CONST_NULL else: box = resumestorage.rd_consts[num - TAG_CONST_OFFSET] elif tag == TAGINT: @@ -61,7 +60,6 @@ return box def serialize_optimizer_knowledge(optimizer, numb_state, liveboxes, liveboxes_from_env, memo): - from rpython.jit.metainterp.history import ConstInt available_boxes = {} for box in liveboxes: if box is not None and box in liveboxes_from_env: @@ -124,7 +122,6 @@ numb_state.append_int(0) def deserialize_optimizer_knowledge(optimizer, resumestorage, frontend_boxes, liveboxes): - from rpython.jit.metainterp.history import ConstInt reader = resumecode.Reader(resumestorage.rd_numb) assert len(frontend_boxes) == len(liveboxes) metainterp_sd = optimizer.metainterp_sd @@ -145,7 +142,7 @@ class_known = bitfield & mask mask >>= 1 if class_known: - cls = optimizer.cpu.ts.cls_of_box(frontend_boxes[i]) + cls = optimizer.cpu.cls_of_box(frontend_boxes[i]) optimizer.make_constant_class(box, cls) # heap knowledge diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -3,7 +3,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.optimizeopt.util import args_dict -from rpython.jit.metainterp.history import Const, ConstInt +from rpython.jit.metainterp.history import Const, ConstInt, new_ref_dict from rpython.jit.metainterp.jitexc import JitException from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method @@ -14,7 +14,7 @@ GuardResOp from rpython.rlib.objectmodel import we_are_translated from rpython.jit.metainterp.optimizeopt import info - + class BogusImmutableField(JitException): @@ -97,7 +97,7 @@ # need any _lazy_set: the heap value is already right. # Note that this may reset to None a non-None lazy_set, # cancelling its previous effects with no side effect. - + # Now, we have to force the item in the short preamble self._getfield(structinfo, op.getdescr(), optheap) self._lazy_set = None @@ -251,7 +251,7 @@ def setup(self): self.optimizer.optheap = self # mapping const value -> info corresponding to it's heap cache - self.const_infos = self.optimizer.cpu.ts.new_ref_dict() + self.const_infos = new_ref_dict() def flush(self): self.cached_dict_reads.clear() diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py --- a/rpython/jit/metainterp/optimizeopt/info.py +++ b/rpython/jit/metainterp/optimizeopt/info.py @@ -15,7 +15,7 @@ class AbstractInfo(AbstractValue): _attrs_ = () - + is_info_class = True def force_box(self, op, optforce): @@ -89,7 +89,7 @@ class NonNullPtrInfo(PtrInfo): _attrs_ = ('last_guard_pos',) last_guard_pos = -1 - + def is_nonnull(self): return True @@ -469,7 +469,7 @@ def setitem_raw(self, offset, itemsize, descr, itemop): self.parent.setitem_raw(self.offset+offset, itemsize, descr, itemop) - + def _force_elements(self, op, optforce, descr): if self.parent.is_virtual(): self.parent._force_elements(op, optforce, descr) @@ -643,7 +643,7 @@ return 0 # annotation hack one_size = len(all_fdescrs) return index * one_size + fielddescr.get_field_descr().get_index() - + def setinteriorfield_virtual(self, index, fielddescr, fld): index = self._compute_index(index, fielddescr) self._items[index] = fld @@ -693,7 +693,7 @@ class ConstPtrInfo(PtrInfo): _attrs_ = ('_const',) - + def __init__(self, const): self._const = const @@ -719,7 +719,7 @@ if info is None: info = ArrayPtrInfo(descr) optheap.const_infos[ref] = info - return info + return info def getfield(self, fielddescr, optheap=None): info = self._get_info(fielddescr.get_parent_descr(), optheap) @@ -755,7 +755,7 @@ # guard_gc_type if not cpu.check_is_object(self._const.getref_base()): return None - return cpu.ts.cls_of_box(self._const) + return cpu.cls_of_box(self._const) def same_info(self, other): if not isinstance(other, ConstPtrInfo): @@ -804,7 +804,7 @@ return -1 return len(s) elif mode is vstring.mode_unicode: - s = self._unpack_str(vstring.mode_unicode) + s = self._unpack_str(vstring.mode_unicode) if s is None: return -1 return len(s) @@ -835,7 +835,7 @@ targetbox, CONST_0, offsetbox, lgt, mode) - + class FloatConstInfo(AbstractInfo): def __init__(self, const): self._const = const diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -1,6 +1,7 @@ from rpython.jit.metainterp import jitprof, resume, compile from rpython.jit.metainterp.executor import execute_nonspec_const -from rpython.jit.metainterp.history import Const, ConstInt, ConstPtr +from rpython.jit.metainterp.history import ( + Const, ConstInt, ConstPtr, CONST_NULL, new_ref_dict) from rpython.jit.metainterp.optimizeopt.intutils import IntBound,\ ConstIntBound, MININT, MAXINT, IntUnbounded from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method @@ -8,7 +9,6 @@ OpHelpers from rpython.jit.metainterp.optimizeopt import info from rpython.jit.metainterp.optimize import InvalidLoop -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.objectmodel import specialize, we_are_translated from rpython.rlib.debug import debug_print from rpython.rtyper import rclass @@ -21,7 +21,6 @@ CONST_0 = ConstInt(0) CONST_1 = ConstInt(1) CONST_ZERO_FLOAT = Const._new(0.0) -llhelper.CONST_NULLREF = llhelper.CONST_NULL REMOVED = AbstractResOp() class LoopInfo(object): @@ -158,7 +157,7 @@ if isinstance(fw, info.AbstractRawPtrInfo): return True return False - + def getrawptrinfo(self, op, create=False, is_object=False): assert op.type == 'i' op = self.get_box_replacement(op) @@ -272,7 +271,7 @@ self.metainterp_sd = metainterp_sd self.jitdriver_sd = jitdriver_sd self.cpu = metainterp_sd.cpu - self.interned_refs = self.cpu.ts.new_ref_dict() + self.interned_refs = new_ref_dict() self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd) self.pendingfields = None # set temporarily to a list, normally by # heap.py, as we're about to generate a guard @@ -464,7 +463,7 @@ def make_nonnull_str(self, op, mode): from rpython.jit.metainterp.optimizeopt import vstring - + op = self.get_box_replacement(op) if op.is_constant(): return @@ -475,7 +474,7 @@ def ensure_ptr_info_arg0(self, op): from rpython.jit.metainterp.optimizeopt import vstring - + arg0 = self.get_box_replacement(op.getarg(0)) if arg0.is_constant(): return info.ConstPtrInfo(arg0) @@ -503,7 +502,7 @@ elif opnum in (rop.GUARD_CLASS, rop.GUARD_NONNULL_CLASS): opinfo = info.InstancePtrInfo() elif opnum in (rop.STRLEN,): - opinfo = vstring.StrPtrInfo(vstring.mode_string) + opinfo = vstring.StrPtrInfo(vstring.mode_string) elif opnum in (rop.UNICODELEN,): opinfo = vstring.StrPtrInfo(vstring.mode_unicode) else: @@ -515,7 +514,7 @@ def new_const(self, fieldofs): if fieldofs.is_pointer_field(): - return self.cpu.ts.CONST_NULL + return CONST_NULL elif fieldofs.is_float_field(): return CONST_ZERO_FLOAT else: @@ -523,7 +522,7 @@ def new_const_item(self, arraydescr): if arraydescr.is_array_of_pointers(): - return self.cpu.ts.CONST_NULL + return CONST_NULL elif arraydescr.is_array_of_floats(): return CONST_ZERO_FLOAT else: diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,8 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.codewriter import longlong from rpython.jit.metainterp import compile -from rpython.jit.metainterp.history import (Const, ConstInt, make_hashable_int, - ConstFloat) +from rpython.jit.metainterp.history import ( + Const, ConstInt, make_hashable_int, ConstFloat, CONST_NULL) from rpython.jit.metainterp.optimize import InvalidLoop From pypy.commits at gmail.com Wed Apr 10 06:54:45 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 10 Apr 2019 03:54:45 -0700 (PDT) Subject: [pypy-commit] pypy arm64: grumble Message-ID: <5cadcb75.1c69fb81.77d46.b814@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96434:8beed1118cdc Date: 2019-04-10 10:54 +0000 http://bitbucket.org/pypy/pypy/changeset/8beed1118cdc/ Log: grumble diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1,7 +1,7 @@ from rpython.jit.backend.aarch64.arch import WORD, JITFRAME_FIXED_SIZE from rpython.jit.backend.aarch64.codebuilder import InstrBuilder, OverwritingBuilder -from rpython.jit.backend.arm.locations import imm, StackLocation, get_fp_offset +from rpython.jit.backend.aarch64.locations import imm, StackLocation, get_fp_offset #from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size from rpython.jit.backend.aarch64.opassembler import ResOpAssembler from rpython.jit.backend.aarch64.regalloc import (Regalloc, diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -122,8 +122,6 @@ base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): - import pdb - pdb.set_trace() try: if not we_are_translated(): assert not self._exception_emulator[0] From pypy.commits at gmail.com Wed Apr 10 06:57:25 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 10 Apr 2019 03:57:25 -0700 (PDT) Subject: [pypy-commit] pypy arm64: one more tests passes Message-ID: <5cadcc15.1c69fb81.d6036.0a79@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96435:1515977fb633 Date: 2019-04-10 10:56 +0000 http://bitbucket.org/pypy/pypy/changeset/1515977fb633/ Log: one more tests passes diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -69,6 +69,10 @@ self.emit_int_comp_op(op, arglocs) return c.LE + def emit_comp_op_int_eq(self, op, arglocs): + self.emit_int_comp_op(op, arglocs) + return c.EQ + def emit_op_increment_debug_counter(self, op, arglocs): return # XXXX base_loc, value_loc = arglocs diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -338,6 +338,7 @@ prepare_comp_op_int_lt = prepare_int_cmp prepare_comp_op_int_le = prepare_int_cmp + prepare_comp_op_int_eq = prepare_int_cmp def prepare_op_int_le(self, op): return self.prepare_int_cmp(op, False) From pypy.commits at gmail.com Wed Apr 10 08:26:48 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 10 Apr 2019 05:26:48 -0700 (PDT) Subject: [pypy-commit] pypy arm64: use full int load for negative numbers Message-ID: <5cade108.1c69fb81.c21d9.91e4@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96436:02d70caf63f3 Date: 2019-04-10 12:26 +0000 http://bitbucket.org/pypy/pypy/changeset/02d70caf63f3/ Log: use full int load for negative numbers diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -165,6 +165,9 @@ """r is the register number, value is the value to be loaded to the register""" # XXX optimize! + if value < 0: + self.gen_load_int_full(r, value) + return self.MOVZ_r_u16(r, value & 0xFFFF, 0) value = value >> 16 shift = 16 From pypy.commits at gmail.com Wed Apr 10 10:27:58 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 10 Apr 2019 07:27:58 -0700 (PDT) Subject: [pypy-commit] pypy arm64: implement a few more int operations Message-ID: <5cadfd6e.1c69fb81.7eb24.d985@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96437:33f62f3022aa Date: 2019-04-10 14:27 +0000 http://bitbucket.org/pypy/pypy/changeset/33f62f3022aa/ Log: implement a few more int operations diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -776,22 +776,22 @@ def not_implemented(msg): - msg = '[ARM/asm] %s\n' % msg + msg = '[ARM64/asm] %s\n' % msg if we_are_translated(): llop.debug_print(lltype.Void, msg) raise NotImplementedError(msg) def notimplemented_op(self, op, arglocs): - print "[ARM/asm] %s not implemented" % op.getopname() + print "[ARM64/asm] %s not implemented" % op.getopname() raise NotImplementedError(op) def notimplemented_comp_op(self, op, arglocs): - print "[ARM/asm] %s not implemented" % op.getopname() + print "[ARM64/asm] %s not implemented" % op.getopname() raise NotImplementedError(op) def notimplemented_guard_op(self, op, fcond, arglocs): - print "[ARM/asm] %s not implemented" % op.getopname() + print "[ARM64/asm] %s not implemented" % op.getopname() raise NotImplementedError(op) asm_operations = [notimplemented_op] * (rop._LAST + 1) diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -110,6 +110,22 @@ base = 0b10001011000 self.write32((base << 21) | (rm << 16) | (rn << 5) | (rd)) + def SUB_rr(self, rd, rn, rm): + base = 0b11001011001 + self.write32((base << 21) | (rm << 16) | (0b11 << 13) | (rn << 5) | (rd)) + + def MUL_rr(self, rd, rn, rm): + base = 0b10011011000 + self.write32((base << 21) | (rm << 16) | (0b11111 << 10) | (rn << 5) | rd) + + def AND_rr(self, rd, rn, rm): + base = 0b10001010000 + self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) + + def EOR_rr(self, rd, rn, rm): + base = 0b11001010000 + self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) + def CMP_rr(self, rn, rm): base = 0b11101011000 self.write32((base << 21) | (rm << 16) | (rn << 5) | 0b11111) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -20,13 +20,7 @@ s = 1 else: s = 0 - if l0.is_imm(): - value = l0.getint() - assert value >= 0 - # reverse substract ftw - XX - self.mc.RSB_ri(res.value, l1.value, value) - elif l1.is_imm(): + if l1.is_imm(): value = l1.getint() assert value >= 0 self.mc.SUB_ri(res.value, l0.value, value) @@ -40,18 +34,33 @@ def int_add_impl(self, op, arglocs, ovfcheck=False): l0, l1, res = arglocs + assert not l0.is_imm() if ovfcheck: XXX s = 1 else: s = 0 - if l0.is_imm(): - self.mc.ADD_ri(res.value, l1.value, l0.value) - elif l1.is_imm(): + if l1.is_imm(): self.mc.ADD_ri(res.value, l0.value, l1.value) else: self.mc.ADD_rr(res.value, l0.value, l1.value) + def emit_op_int_mul(self, op, arglocs): + reg1, reg2, res = arglocs + self.mc.MUL_rr(res.value, reg1.value, reg2.value) + + def emit_op_int_and(self, op, arglocs): + l0, l1, res = arglocs + self.mc.AND_rr(res.value, l0.value, l1.value) + + def emit_op_int_or(self, op, arglocs): + l0, l1, res = arglocs + self.mc.ORR_rr(res.value, l0.value, l1.value) + + def emit_op_int_xor(self, op, arglocs): + l0, l1, res = arglocs + self.mc.EOR_rr(res.value, l0.value, l1.value) + def emit_int_comp_op(self, op, arglocs): l0, l1 = arglocs diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -298,7 +298,7 @@ self.free_temp_vars() return [base_loc, value_loc] - def prepare_op_int_add(self, op): + def prepare_int_ri(self, op): boxes = op.getarglist() a0, a1 = boxes imm_a0 = check_imm_box(a0) @@ -307,8 +307,8 @@ l0 = self.make_sure_var_in_reg(a0, boxes) l1 = self.convert_to_imm(a1) elif imm_a0 and not imm_a1: - l0 = self.convert_to_imm(a0) - l1 = self.make_sure_var_in_reg(a1, boxes) + l1 = self.convert_to_imm(a0) + l0 = self.make_sure_var_in_reg(a1, boxes) else: l0 = self.make_sure_var_in_reg(a0, boxes) l1 = self.make_sure_var_in_reg(a1, boxes) @@ -316,7 +316,38 @@ res = self.force_allocate_reg(op) return [l0, l1, res] - prepare_op_int_sub = prepare_op_int_add + prepare_op_int_add = prepare_int_ri + + def prepare_op_int_sub(self, op): + boxes = op.getarglist() + a0, a1 = boxes + imm_a1 = check_imm_box(a1) + if imm_a1: + l0 = self.make_sure_var_in_reg(a0, boxes) + l1 = self.convert_to_imm(a1) + else: + l0 = self.make_sure_var_in_reg(a0, boxes) + l1 = self.make_sure_var_in_reg(a1, boxes) + self.possibly_free_vars_for_op(op) + res = self.force_allocate_reg(op) + return [l0, l1, res] + + def prepare_op_int_mul(self, op): + boxes = op.getarglist() + a0, a1 = boxes + + reg1 = self.make_sure_var_in_reg(a0, forbidden_vars=boxes) + reg2 = self.make_sure_var_in_reg(a1, forbidden_vars=boxes) + + self.possibly_free_vars(boxes) + self.possibly_free_vars_for_op(op) + res = self.force_allocate_reg(op) + self.possibly_free_var(op) + return [reg1, reg2, res] + + prepare_op_int_and = prepare_op_int_mul + prepare_op_int_or = prepare_op_int_mul + prepare_op_int_xor = prepare_op_int_mul def prepare_int_cmp(self, op, res_in_cc): boxes = op.getarglist() From pypy.commits at gmail.com Wed Apr 10 23:18:16 2019 From: pypy.commits at gmail.com (mattip) Date: Wed, 10 Apr 2019 20:18:16 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: test, fix for strip(buffer) Message-ID: <5caeb1f8.1c69fb81.b94d.f4d7@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96440:4ff72cf6b182 Date: 2019-04-11 06:17 +0300 http://bitbucket.org/pypy/pypy/changeset/4ff72cf6b182/ Log: test, fix for strip(buffer) diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -524,6 +524,7 @@ assert 'xyzzyhelloxyzzy'.strip('xyz') == 'hello' assert 'xyzzyhelloxyzzy'.lstrip('xyz') == 'helloxyzzy' assert 'xyzzyhelloxyzzy'.rstrip('xyz') == 'xyzzyhello' + raises(TypeError, s.strip, bytearray(b'a')) def test_long_from_unicode(self): assert int('12345678901234567890') == 12345678901234567890 diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -134,7 +134,7 @@ "Can't convert '%T' object to str implicitly", w_other) if strict: raise oefmt(space.w_TypeError, - "%s arg must be None, unicode or str", strict) + "%s arg must be None or str", strict) return decode_object(space, w_other, 'utf8', "strict") def convert_to_w_unicode(self, space): @@ -1135,7 +1135,7 @@ def _strip(self, space, w_chars, left, right, name='strip'): "internal function called by str_xstrip methods" value = self._utf8 - chars = self.convert_arg_to_w_unicode(space, w_chars)._utf8 + chars = self.convert_arg_to_w_unicode(space, w_chars, name)._utf8 lpos = 0 rpos = len(value) From pypy.commits at gmail.com Thu Apr 11 01:31:02 2019 From: pypy.commits at gmail.com (mattip) Date: Wed, 10 Apr 2019 22:31:02 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: test, fix for u'a' < bytearray(b'a') which should raise Message-ID: <5caed116.1c69fb81.9b5de.3955@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96441:4b54eb2f7e85 Date: 2019-04-11 08:30 +0300 http://bitbucket.org/pypy/pypy/changeset/4b54eb2f7e85/ Log: test, fix for u'a' < bytearray(b'a') which should raise diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -201,6 +201,7 @@ assert not ('a' == 5) assert 'a' != 5 raises(TypeError, "'a' < 5") + raises(TypeError, "'a' < bytearray(b'a')") class AppTestUnicodeString: diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -329,7 +329,8 @@ def descr_lt(self, space, w_other): try: - res = self._utf8 < self.convert_arg_to_w_unicode(space, w_other)._utf8 + res = self._utf8 < self.convert_arg_to_w_unicode(space, w_other, + strict='__lt__')._utf8 except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented @@ -338,7 +339,8 @@ def descr_le(self, space, w_other): try: - res = self._utf8 <= self.convert_arg_to_w_unicode(space, w_other)._utf8 + res = self._utf8 <= self.convert_arg_to_w_unicode(space, w_other, + strict='__le__')._utf8 except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented @@ -347,7 +349,8 @@ def descr_gt(self, space, w_other): try: - res = self._utf8 > self.convert_arg_to_w_unicode(space, w_other)._utf8 + res = self._utf8 > self.convert_arg_to_w_unicode(space, w_other, + strict='__gt__')._utf8 except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented @@ -356,7 +359,8 @@ def descr_ge(self, space, w_other): try: - res = self._utf8 >= self.convert_arg_to_w_unicode(space, w_other)._utf8 + res = self._utf8 >= self.convert_arg_to_w_unicode(space, w_other, + strict='__ge__')._utf8 except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented From pypy.commits at gmail.com Thu Apr 11 03:01:43 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 00:01:43 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix memoryview(ctype_struct) for padding, fixes cpython bpo-32780 Message-ID: <5caee657.1c69fb81.92dfa.b0f3@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96442:58997e887cf5 Date: 2019-04-11 09:54 +0300 http://bitbucket.org/pypy/pypy/changeset/58997e887cf5/ Log: fix memoryview(ctype_struct) for padding, fixes cpython bpo-32780 diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -296,7 +296,11 @@ else: bo = byteorder[sys.byteorder] flds = [] + cum_size = 0 for name, obj in typ._fields_: + padding = typ._ffistruct_.fieldoffset(name) - cum_size + if padding: + flds.append('%dx' % padding) # Trim off the leading '<' or '>' ch = get_format_str(obj)[1:] if (ch) == 'B': @@ -307,6 +311,7 @@ flds.append(':') flds.append(name) flds.append(':') + cum_size += typ._ffistruct_.fieldsize(name) return 'T{' + ''.join(flds) + '}' elif hasattr(typ, '_type_'): ch = typ._type_ From pypy.commits at gmail.com Thu Apr 11 03:18:19 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 00:18:19 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: merge default into branch Message-ID: <5caeea3b.1c69fb81.3cd8.e7a6@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96444:22c72d0632dc Date: 2019-04-11 10:17 +0300 http://bitbucket.org/pypy/pypy/changeset/22c72d0632dc/ Log: merge default into branch diff too long, truncating to 2000 out of 6755 lines diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -113,10 +114,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -141,18 +146,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -260,7 +268,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -387,7 +396,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -423,13 +433,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -451,8 +463,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -512,11 +526,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -592,7 +608,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -616,7 +633,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -634,7 +652,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -658,18 +677,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -688,7 +710,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -913,10 +936,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -951,11 +978,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1012,17 +1042,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1280,7 +1316,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py --- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py +++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py @@ -130,6 +130,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -269,12 +299,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py --- a/extra_tests/cffi_tests/cffi0/test_function.py +++ b/extra_tests/cffi_tests/cffi0/test_function.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -91,7 +92,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -467,3 +467,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * @@ -21,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -590,7 +592,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +651,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1468,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1539,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2106,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py --- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py +++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -86,9 +87,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -187,10 +188,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -213,18 +218,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -325,7 +333,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -446,7 +455,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -479,13 +489,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -503,8 +515,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -556,11 +570,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -626,7 +642,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -649,7 +666,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -665,7 +683,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -686,17 +705,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -714,7 +736,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -923,10 +946,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -948,11 +975,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1001,17 +1031,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1236,7 +1272,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1753,7 +1790,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -1,6 +1,7 @@ # Generated by pypy/tool/import_cffi.py import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from extra_tests.cffi_tests.udir import udir @@ -189,20 +190,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -248,7 +255,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -264,7 +272,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -316,8 +325,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -388,8 +399,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -399,8 +412,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1021,8 +1036,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1035,7 +1052,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1044,8 +1062,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1055,7 +1075,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1065,8 +1086,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1339,7 +1362,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -23,7 +24,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error @@ -572,7 +574,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +633,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1438,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1509,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2201,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -173,7 +173,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -498,6 +498,15 @@ * Dictionaries and sets are ordered on PyPy. On CPython < 3.6 they are not; on CPython >= 3.6 dictionaries (but not sets) are ordered. +* PyPy2 refuses to load lone ``.pyc`` files, i.e. ``.pyc`` files that are + still there after you deleted the ``.py`` file. PyPy3 instead behaves like + CPython. We could be amenable to fix this difference in PyPy2: the current + version reflects `our annoyance`__ with this detail of CPython, which bit + us too often while developing PyPy. (It is as easy as passing the + ``--lonepycfile`` flag when translating PyPy, if you really need it.) + +.. __: https://stackoverflow.com/a/55499713/1556290 + .. _extension-modules: diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -9,3 +9,6 @@ Fix typo +.. branch: jit-cleanup + +Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -402,15 +402,22 @@ # bypass the method 'string' implemented in W_CTypePrimitive return W_CType.string(self, cdataobj, maxlen) - def convert_to_object(self, cdata): - space = self.space + def _read_bool_0_or_1(self, cdata): + """Read one byte, check it is 0 or 1, but return it as an integer""" value = ord(cdata[0]) - if value < 2: - return space.newbool(value != 0) - else: - raise oefmt(space.w_ValueError, + if value >= 2: + raise oefmt(self.space.w_ValueError, "got a _Bool of value %d, expected 0 or 1", value) + return value + + def convert_to_object(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newbool(value != 0) + + def cast_to_int(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newint(value) def unpack_list_of_int_items(self, ptr, length): return None diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -304,8 +304,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -433,7 +435,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -526,13 +529,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -547,10 +553,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -598,10 +608,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -614,8 +628,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -766,10 +782,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -781,30 +799,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1625,7 +1654,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1755,14 +1785,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1771,7 +1804,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1831,14 +1865,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2170,8 +2207,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): + s.a1 = b'a' + with pytest.raises(TypeError): + s.a1 = bytechr(0xFF) s.a1 = u+'\u1234' assert s.a1 == u+'\u1234' if pyuni4: @@ -2185,7 +2224,8 @@ s.a1 = u+'\ud807\udf44' assert s.a1 == u+'\U00011f44' else: - py.test.raises(TypeError, "s.a1 = u+'\U00012345'") + with pytest.raises(TypeError): + s.a1 = u+'\U00012345' # BWCharArray = new_array_type(BWCharP, None) a = newp(BWCharArray, u+'hello \u1234 world') @@ -2209,7 +2249,8 @@ assert list(a) == expected got = [a[i] for i in range(4)] assert got == expected - py.test.raises(IndexError, 'a[4]') + with pytest.raises(IndexError): + a[4] # w = cast(BWChar, 'a') assert repr(w) == "" % (typename, mandatory_u_prefix) @@ -2341,9 +2382,11 @@ def test_cannot_dereference_void(): BVoidP = new_pointer_type(new_void_type()) p = cast(BVoidP, 123456) - py.test.raises(TypeError, "p[0]") + with pytest.raises(TypeError): + p[0] p = cast(BVoidP, 0) - py.test.raises((TypeError, RuntimeError), "p[0]") + with pytest.raises((TypeError, RuntimeError)): + p[0] def test_iter(): BInt = new_primitive_type("int") @@ -2366,12 +2409,12 @@ assert (q == p) is False assert (q != p) is True if strict_compare: - py.test.raises(TypeError, "p < q") - py.test.raises(TypeError, "p <= q") - py.test.raises(TypeError, "q < p") - py.test.raises(TypeError, "q <= p") - py.test.raises(TypeError, "p > q") - py.test.raises(TypeError, "p >= q") + with pytest.raises(TypeError): p < q + with pytest.raises(TypeError): p <= q + with pytest.raises(TypeError): q < p + with pytest.raises(TypeError): q <= p + with pytest.raises(TypeError): p > q + with pytest.raises(TypeError): p >= q r = cast(BVoidP, p) assert (p < r) is False assert (p <= r) is True @@ -2417,7 +2460,8 @@ try: expected = b"hi there\x00"[i] except IndexError: - py.test.raises(IndexError, "buf[i]") + with pytest.raises(IndexError): + buf[i] else: assert buf[i] == bitem2bchr(expected) # --mb_slice-- @@ -2444,15 +2488,18 @@ try: expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + with pytest.raises(IndexError): + buf[i] = bytechr(i & 0xff) else: buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) - py.test.raises(ValueError, 'buf[:] = b"shorter"') - py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + with pytest.raises(ValueError): + buf[:] = b"shorter" + with pytest.raises(ValueError): + buf[:] = b"this is much too long!" buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" buf[:2] = b"HI" @@ -2526,14 +2573,16 @@ BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) x = newp(BCharP) - py.test.raises(TypeError, "del x[0]") + with pytest.raises(TypeError): + del x[0] def test_bug_delattr(): BLong = new_primitive_type("long") BStruct = new_struct_type("struct foo") complete_struct_or_union(BStruct, [('a1', BLong, -1)]) x = newp(new_pointer_type(BStruct)) - py.test.raises(AttributeError, "del x.a1") + with pytest.raises(AttributeError): + del x.a1 def test_variable_length_struct(): py.test.skip("later") @@ -2551,7 +2600,8 @@ assert sizeof(x) == 6 * size_of_long() x[4] = 123 assert x[4] == 123 - py.test.raises(IndexError, "x[5]") + with pytest.raises(IndexError): + x[5] assert len(x.a2) == 5 # py.test.raises(TypeError, newp, BStructP, [123]) @@ -2803,7 +2853,8 @@ BCharP = new_pointer_type(new_primitive_type("char")) p = newp(BCharP, b'X') q = cast(BBoolP, p) - py.test.raises(ValueError, "q[0]") + with pytest.raises(ValueError): + q[0] py.test.raises(TypeError, newp, BBoolP, b'\x00') assert newp(BBoolP, 0)[0] is False assert newp(BBoolP, 1)[0] is True @@ -3103,8 +3154,10 @@ assert c[1] == 123 assert c[3] == 456 assert d[2] == 456 - py.test.raises(IndexError, "d[3]") - py.test.raises(IndexError, "d[-1]") + with pytest.raises(IndexError): + d[3] + with pytest.raises(IndexError): + d[-1] def test_slice_ptr(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -3122,7 +3175,8 @@ c = newp(BIntArray, 5) c[0:5] assert len(c[5:5]) == 0 - py.test.raises(IndexError, "c[-1:1]") + with pytest.raises(IndexError): + c[-1:1] cp = c + 0 cp[-1:1] @@ -3130,17 +3184,23 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) - e = py.test.raises(IndexError, "c[:5]") + with pytest.raises(IndexError) as e: + c[:5] assert str(e.value) == "slice start must be specified" - e = py.test.raises(IndexError, "c[4:]") + with pytest.raises(IndexError) as e: + c[4:] assert str(e.value) == "slice stop must be specified" - e = py.test.raises(IndexError, "c[1:2:3]") + with pytest.raises(IndexError) as e: + c[1:2:3] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[1:2:1]") + with pytest.raises(IndexError) as e: + c[1:2:1] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[4:2]") + with pytest.raises(IndexError) as e: + c[4:2] assert str(e.value) == "slice start > stop" - e = py.test.raises(IndexError, "c[6:6]") + with pytest.raises(IndexError) as e: + c[6:6] assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): @@ -3154,9 +3214,11 @@ assert list(c) == [0, 100, 300, 400, 0] cp[-1:1] = iter([500, 600]) assert list(c) == [0, 100, 500, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = [1000]") + with pytest.raises(ValueError): + cp[-1:1] = [1000] assert list(c) == [0, 100, 1000, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + with pytest.raises(ValueError): + cp[-1:1] = (700, 800, 900) assert list(c) == [0, 100, 700, 800, 0] def test_setslice_array(): @@ -3416,10 +3478,14 @@ assert sizeof(q[0]) == sizeof(BStruct) # # error cases - py.test.raises(IndexError, "p.y[4]") - py.test.raises(TypeError, "p.y = cast(BIntP, 0)") - py.test.raises(TypeError, "p.y = 15") - py.test.raises(TypeError, "p.y = None") + with pytest.raises(IndexError): + p.y[4] + with pytest.raises(TypeError): + p.y = cast(BIntP, 0) + with pytest.raises(TypeError): + p.y = 15 + with pytest.raises(TypeError): + p.y = None # # accepting this may be specified by the C99 standard, # or a GCC strangeness... @@ -3524,8 +3590,10 @@ p[2:5] = [b"*", b"Z", b"T"] p[1:3] = b"XY" assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"] - py.test.raises(TypeError, "p[1:5] = u+'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = u+'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] # for typename in ["wchar_t", "char16_t", "char32_t"]: BUniChar = new_primitive_type(typename) @@ -3534,8 +3602,10 @@ p[2:5] = [u+"*", u+"Z", u+"T"] p[1:3] = u+"XY" assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"] - py.test.raises(TypeError, "p[1:5] = b'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = b'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] def test_void_p_arithmetic(): BVoid = new_void_type() @@ -3546,10 +3616,14 @@ assert int(cast(BInt, p - (-42))) == 100042 assert (p + 42) - p == 42 q = cast(new_pointer_type(new_primitive_type("char")), 100000) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)") - py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + p + cast(new_primitive_type('int'), 42) + with pytest.raises(TypeError): + p - cast(new_primitive_type('int'), 42) def test_sizeof_sliced_array(): BInt = new_primitive_type("int") @@ -3764,8 +3838,10 @@ assert p1[0] == lst[0] assert p1[1] == lst[1] assert p1[2] == lst[2] - py.test.raises(IndexError, "p1[3]") - py.test.raises(IndexError, "p1[-1]") + with pytest.raises(IndexError): + p1[3] + with pytest.raises(IndexError): + p1[-1] # py.test.raises(TypeError, from_buffer, BInt, bytestring) py.test.raises(TypeError, from_buffer, BIntP, bytestring) @@ -3776,8 +3852,10 @@ assert len(p2) == 2 assert p2[0] == lst[0] assert p2[1] == lst[1] - py.test.raises(IndexError, "p2[2]") - py.test.raises(IndexError, "p2[-1]") + with pytest.raises(IndexError): + p2[2] + with pytest.raises(IndexError): + p2[-1] assert p2 == p1 # BIntA4 = new_array_type(BIntP, 4) # int[4]: too big @@ -3793,7 +3871,8 @@ assert typeof(p1) is BStructA assert p1[0].a1 == lst[0] assert p1[0].a2 == lst[1] - py.test.raises(IndexError, "p1[1]") + with pytest.raises(IndexError): + p1[1] # BEmptyStruct = new_struct_type("empty") complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) @@ -3885,10 +3964,14 @@ BInt = new_primitive_type("int") BIntPtr = new_pointer_type(BInt) p = cast(BIntPtr, 0) - py.test.raises(RuntimeError, "p[0]") - py.test.raises(RuntimeError, "p[0] = 42") - py.test.raises(RuntimeError, "p[42]") - py.test.raises(RuntimeError, "p[42] = -1") + with pytest.raises(RuntimeError): + p[0] + with pytest.raises(RuntimeError): + p[0] = 42 + with pytest.raises(RuntimeError): + p[42] + with pytest.raises(RuntimeError): + p[42] = -1 def test_mixup(): BStruct1 = new_struct_type("foo") @@ -3904,10 +3987,12 @@ pp2 = newp(BStruct2PtrPtr) pp3 = newp(BStruct3PtrPtr) pp1[0] = pp1[0] - e = py.test.raises(TypeError, "pp3[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp3[0] = pp1[0] assert str(e.value).startswith("initializer for ctype 'bar *' must be a ") assert str(e.value).endswith(", not cdata 'foo *'") - e = py.test.raises(TypeError, "pp2[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp2[0] = pp1[0] assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to " "be 'foo *', but the types are different (check " "that you are not e.g. mixing up different ffi " @@ -4096,14 +4181,14 @@ assert (a != b) is True assert (b != a) is True if strict_compare: - py.test.raises(TypeError, "a < b") - py.test.raises(TypeError, "a <= b") - py.test.raises(TypeError, "a > b") - py.test.raises(TypeError, "a >= b") - py.test.raises(TypeError, "b < a") - py.test.raises(TypeError, "b <= a") - py.test.raises(TypeError, "b > a") - py.test.raises(TypeError, "b >= a") + with pytest.raises(TypeError): a < b + with pytest.raises(TypeError): a <= b + with pytest.raises(TypeError): a > b + with pytest.raises(TypeError): a >= b + with pytest.raises(TypeError): b < a + with pytest.raises(TypeError): b <= a + with pytest.raises(TypeError): b > a + with pytest.raises(TypeError): b >= a elif a < b: assert_lt(a, b) else: @@ -4149,7 +4234,8 @@ BIntP = new_pointer_type(new_primitive_type("int")) p = newp(BIntP) p[0] = 42 - py.test.raises(IndexError, "p[1]") + with pytest.raises(IndexError): + p[1] release(p) # here, reading p[0] might give garbage or segfault... release(p) # no effect @@ -4185,8 +4271,12 @@ def test_explicit_release_badtype_contextmgr(): BIntP = new_pointer_type(new_primitive_type("int")) p = cast(BIntP, 12345) - py.test.raises(ValueError, "with p: pass") - py.test.raises(ValueError, "with p: pass") + with pytest.raises(ValueError): + with p: + pass + with pytest.raises(ValueError): + with p: + pass def test_explicit_release_gc(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -4246,9 +4336,21 @@ BCharA = new_array_type(BCharP, None) a += b't' * 10 p = from_buffer(BCharA, a) - py.test.raises(BufferError, "a += b'u' * 100") + with pytest.raises(BufferError): + a += b'u' * 100 release(p) a += b'v' * 100 release(p) # no effect a += b'w' * 1000 assert a == bytearray(b"xyz" + b't' * 10 + b'v' * 100 + b'w' * 1000) + +def test_int_doesnt_give_bool(): + BBool = new_primitive_type("_Bool") + x = int(cast(BBool, 42)) + assert type(x) is int and x == 1 + x = long(cast(BBool, 42)) + assert type(x) is long and x == 1 + with pytest.raises(TypeError): + float(cast(BBool, 42)) + with pytest.raises(TypeError): + complex(cast(BBool, 42)) diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -138,6 +138,7 @@ print >> f, ' class test:' print >> f, ' raises = staticmethod(raises)' print >> f, ' skip = staticmethod(skip)' + print >> f, 'pytest = py.test' print >> f, backend_test_c.read() diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -13,7 +13,6 @@ from pypy.module.pypyjit.interp_jit import pypyjitdriver from pypy.module.pypyjit.hooks import pypy_hooks from rpython.jit.tool.oparser import parse -from rpython.jit.metainterp.typesystem import llhelper from rpython.rlib.jit import JitDebugInfo, AsmInfo, Counters @@ -31,7 +30,7 @@ class MockSD(object): class cpu(object): - ts = llhelper + pass jitdrivers_sd = [MockJitDriverSD] diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py --- a/pypy/tool/pytest/appsupport.py +++ b/pypy/tool/pytest/appsupport.py @@ -1,7 +1,7 @@ from inspect import CO_VARARGS, CO_VARKEYWORDS import py -from pypy.interpreter import gateway, pycode +from pypy.interpreter import gateway, pycode, typedef, baseobjspace from pypy.interpreter.error import OperationError, oefmt try: @@ -225,8 +225,42 @@ return e """) -def pypyraises(space, w_ExpectedException, w_expr, __args__): + +class W_RaisesContextManager(baseobjspace.W_Root): + # Note: this is here because of _cffi_backend/test/test_c.py + def __init__(self, space, w_ExpectedException): + self.space = space + self.w_ExpectedException = w_ExpectedException + + def enter(self): + return self + + def exit(self, w_exc_type, w_exc_value, w_traceback): + space = self.space + if space.is_none(w_exc_type): + self.report_error("no exception") + if not space.exception_match(w_exc_type, self.w_ExpectedException): + self.report_error(space.text_w(space.repr(w_exc_type))) + self.w_value = w_exc_value # for the 'value' app-level attribute + return space.w_True # suppress the exception + + def report_error(self, got): + space = self.space + raise oefmt(space.w_AssertionError, + "raises() expected %s, but got %s", + space.text_w(space.repr(self.w_ExpectedException)), + got) + +W_RaisesContextManager.typedef = typedef.TypeDef("RaisesContextManager", + __enter__ = gateway.interp2app_temp(W_RaisesContextManager.enter), + __exit__ = gateway.interp2app_temp(W_RaisesContextManager.exit), + value = typedef.interp_attrproperty_w('w_value', cls=W_RaisesContextManager) + ) + +def pypyraises(space, w_ExpectedException, w_expr=None, __args__=None): """A built-in function providing the equivalent of py.test.raises().""" + if w_expr is None: + return W_RaisesContextManager(space, w_ExpectedException) args_w, kwds_w = __args__.unpack() if space.isinstance_w(w_expr, space.w_text): if args_w: diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -99,7 +99,7 @@ if sys.platform == 'win32' and not rename_pypy_c.lower().endswith('.exe'): rename_pypy_c += '.exe' - binaries = [(pypy_c, rename_pypy_c)] + binaries = [(pypy_c, rename_pypy_c, None)] if (sys.platform != 'win32' and # handled below not _fake and os.path.getsize(str(pypy_c)) < 500000): @@ -111,10 +111,12 @@ if not libpypy_c.check(): raise PyPyCNotFound('Expected pypy to be mostly in %r, but did ' 'not find it' % (str(libpypy_c),)) - binaries.append((libpypy_c, libpypy_name)) + binaries.append((libpypy_c, libpypy_name, None)) # builddir = py.path.local(options.builddir) pypydir = builddir.ensure(name, dir=True) + lib_pypy = pypydir.join('lib_pypy') + # do not create lib_pypy yet, it will be created by the copytree below includedir = basedir.join('include') shutil.copytree(str(includedir), str(pypydir.join('include'))) @@ -123,18 +125,19 @@ if sys.platform == 'win32': os.environ['PATH'] = str(basedir.join('externals').join('bin')) + ';' + \ os.environ.get('PATH', '') - src,tgt = binaries[0] + src, tgt, _ = binaries[0] pypyw = src.new(purebasename=src.purebasename + 'w') if pypyw.exists(): tgt = py.path.local(tgt) - binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 'w').basename)) + binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 'w').basename, None)) print "Picking %s" % str(pypyw) # Can't rename a DLL: it is always called 'libpypy3-c.dll' - win_extras = ['libpypy3-c.dll', 'sqlite3.dll'] + win_extras = [('libpypy3-c.dll', None), ('sqlite3.dll', lib_pypy)] if not options.no_tk: - win_extras += ['tcl85.dll', 'tk85.dll'] + tkinter_dir = lib_pypy.join('_tkinter') + win_extras += [('tcl85.dll', tkinter_dir), ('tk85.dll', tkinter_dir)] - for extra in win_extras: + for extra,target_dir in win_extras: p = pypy_c.dirpath().join(extra) if not p.check(): p = py.path.local.sysfind(extra) @@ -142,7 +145,7 @@ print "%s not found, expect trouble if this is a shared build" % (extra,) continue print "Picking %s" % p - binaries.append((p, p.basename)) + binaries.append((p, p.basename, target_dir)) libsdir = basedir.join('libs') if libsdir.exists(): print 'Picking %s (and contents)' % libsdir @@ -174,7 +177,7 @@ raise MissingDependenciesError('Tk runtime') print '* Binaries:', [source.relto(str(basedir)) - for source, target in binaries] + for source, target, target_dir in binaries] # Careful: to copy lib_pypy, copying just the hg-tracked files # would not be enough: there are also ctypes_config_cache/_*_cache.py. @@ -182,15 +185,14 @@ shutil.copytree(str(basedir.join('lib-python').join(STDLIB_VER)), str(pypydir.join('lib-python').join(STDLIB_VER)), ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~')) - shutil.copytree(str(basedir.join('lib_pypy')), - str(pypydir.join('lib_pypy')), + shutil.copytree(str(basedir.join('lib_pypy')), str(lib_pypy), From pypy.commits at gmail.com Thu Apr 11 06:17:56 2019 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 11 Apr 2019 03:17:56 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: test and fix for issue #2995 Message-ID: <5caf1454.1c69fb81.81057.587d@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96445:07207a5d3411 Date: 2019-04-11 12:14 +0200 http://bitbucket.org/pypy/pypy/changeset/07207a5d3411/ Log: test and fix for issue #2995 diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -923,6 +923,9 @@ values_count = len(values) if targets_count != values_count: return False + for value in values: + if isinstance(value, ast.Starred): + return False # more complicated for target in targets: if not isinstance(target, ast.Name): if isinstance(target, ast.Starred): diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1115,6 +1115,13 @@ """ yield self.st, func, "f()", [4, 5, 6, 7] + func = """def f(): + b = [4,] + x, y = (*b, 7) + return x + """ + yield self.st, func, "f()", 4 + def test_extended_unpacking_fail(self): exc = py.test.raises(SyntaxError, self.simple_test, "*a, *b = [1, 2]", From pypy.commits at gmail.com Thu Apr 11 07:39:05 2019 From: pypy.commits at gmail.com (fijal) Date: Thu, 11 Apr 2019 04:39:05 -0700 (PDT) Subject: [pypy-commit] pypy arm64: more int operations Message-ID: <5caf2759.1c69fb81.a721.cb24@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96446:802c95aa855a Date: 2019-04-11 11:37 +0000 http://bitbucket.org/pypy/pypy/changeset/802c95aa855a/ Log: more int operations diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -118,10 +118,26 @@ base = 0b10011011000 self.write32((base << 21) | (rm << 16) | (0b11111 << 10) | (rn << 5) | rd) + def UMULH_rr(self, rd, rn, rm): + base = 0b10011011110 + self.write32((base << 21) | (rm << 16) | (0b11111 << 10) | (rn << 5) | rd) + def AND_rr(self, rd, rn, rm): base = 0b10001010000 self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) + def LSL_rr(self, rd, rn, rm): + base = 0b10011010110 + self.write32((base << 21) | (rm << 16) | (0b001000 << 10) | (rn << 5) | rd) + + def ASR_rr(self, rd, rn, rm): + base = 0b10011010110 + self.write32((base << 21) | (rm << 16) | (0b001010 << 10) | (rn << 5) | rd) + + def LSR_rr(self, rd, rn, rm): + base = 0b10011010110 + self.write32((base << 21) | (rm << 16) | (0b001001 << 10) | (rn << 5) | rd) + def EOR_rr(self, rd, rn, rm): base = 0b11001010000 self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) @@ -135,6 +151,11 @@ assert 0 <= imm <= 4095 self.write32((base << 22) | (imm << 10) | (rn << 5) | 0b11111) + def CSET_r_flag(self, rd, cond): + base = 0b10011010100 + self.write32((base << 21) | (0b11111 << 16) | (cond << 12) | (1 << 10) | + (0b11111 << 5) | rd) + def NOP(self): self.write32(0b11010101000000110010000000011111) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -8,6 +8,17 @@ from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import TargetToken +def gen_comp_op(name, flag): + def emit_op(self, op, arglocs): + l0, l1, res = arglocs + + if l1.is_imm(): + self.mc.CMP_ri(l0.value, l1.getint()) + else: + self.mc.CMP_rr(l0.value, l1.value) + self.mc.CSET_r_flag(res.value, c.get_opposite_of(flag)) + emit_op.__name__ = name + return emit_op class ResOpAssembler(BaseAssembler): def emit_op_int_add(self, op, arglocs): @@ -61,12 +72,27 @@ l0, l1, res = arglocs self.mc.EOR_rr(res.value, l0.value, l1.value) + def emit_op_int_lshift(self, op, arglocs): + l0, l1, res = arglocs + self.mc.LSL_rr(res.value, l0.value, l1.value) + + def emit_op_int_rshift(self, op, arglocs): + l0, l1, res = arglocs + self.mc.ASR_rr(res.value, l0.value, l1.value) + + def emit_op_uint_rshift(self, op, arglocs): + l0, l1, res = arglocs + self.mc.LSR_rr(res.value, l0.value, l1.value) + + def emit_op_uint_mul_high(self, op, arglocs): + l0, l1, res = arglocs + self.mc.UMULH_rr(res.value, l0.value, l1.value) + def emit_int_comp_op(self, op, arglocs): l0, l1 = arglocs if l1.is_imm(): - xxx - self.mc.CMP_ri(l0.value, imm=l1.getint(), cond=fcond) + self.mc.CMP_ri(l0.value, l1.getint()) else: self.mc.CMP_rr(l0.value, l1.value) @@ -82,6 +108,13 @@ self.emit_int_comp_op(op, arglocs) return c.EQ + emit_op_int_lt = gen_comp_op('emit_op_int_lt', c.LT) + emit_op_int_le = gen_comp_op('emit_op_int_le', c.LE) + emit_op_int_gt = gen_comp_op('emit_op_int_gt', c.GT) + emit_op_int_ge = gen_comp_op('emit_op_int_ge', c.GE) + emit_op_int_eq = gen_comp_op('emit_op_int_eq', c.EQ) + emit_op_int_ne = gen_comp_op('emit_op_int_ne', c.NE) + def emit_op_increment_debug_counter(self, op, arglocs): return # XXXX base_loc, value_loc = arglocs diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -345,14 +345,20 @@ self.possibly_free_var(op) return [reg1, reg2, res] + # some of those have forms of imm that they accept, but they're rather + # obscure. Can be future optimization prepare_op_int_and = prepare_op_int_mul prepare_op_int_or = prepare_op_int_mul prepare_op_int_xor = prepare_op_int_mul + prepare_op_int_lshift = prepare_op_int_mul + prepare_op_int_rshift = prepare_op_int_mul + prepare_op_uint_rshift = prepare_op_int_mul + prepare_op_uint_mul_high = prepare_op_int_mul def prepare_int_cmp(self, op, res_in_cc): boxes = op.getarglist() arg0, arg1 = boxes - imm_a1 = False # XXX check_imm_box(arg1) + imm_a1 = check_imm_box(arg1) l0 = self.make_sure_var_in_reg(arg0, forbidden_vars=boxes) if imm_a1: @@ -363,7 +369,7 @@ self.possibly_free_vars_for_op(op) self.free_temp_vars() if not res_in_cc: - res = self.force_allocate_reg_or_cc(op) + res = self.force_allocate_reg(op) return [l0, l1, res] return [l0, l1] @@ -374,6 +380,12 @@ def prepare_op_int_le(self, op): return self.prepare_int_cmp(op, False) + prepare_op_int_lt = prepare_op_int_le + prepare_op_int_gt = prepare_op_int_le + prepare_op_int_ge = prepare_op_int_le + prepare_op_int_eq = prepare_op_int_le + prepare_op_int_ne = prepare_op_int_le + def prepare_op_label(self, op): descr = op.getdescr() assert isinstance(descr, TargetToken) From pypy.commits at gmail.com Thu Apr 11 08:44:35 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 05:44:35 -0700 (PDT) Subject: [pypy-commit] pypy release-pypy2.7-v7.x: update version to 7.1.1 Message-ID: <5caf36b3.1c69fb81.4eecd.7e76@mx.google.com> Author: Matti Picus Branch: release-pypy2.7-v7.x Changeset: r96448:ec8165ce733b Date: 2019-04-11 14:38 +0300 http://bitbucket.org/pypy/pypy/changeset/ec8165ce733b/ Log: update version to 7.1.1 diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -32,8 +32,8 @@ * module/sys/version.py * doc/conf.py */ -#define PYPY_VERSION "7.1.0" -#define PYPY_VERSION_NUM 0x07010000 +#define PYPY_VERSION "7.1.1" +#define PYPY_VERSION_NUM 0x07010100 /* Defined to mean a PyPy where cpyext holds more regular references to PyObjects, e.g. staying alive as long as the internal PyPy object stays alive. */ diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -13,7 +13,7 @@ # make sure to keep PYPY_VERSION in sync with: # module/cpyext/include/patchlevel.h # doc/conf.py -PYPY_VERSION = (7, 1, 0, "final", 0) +PYPY_VERSION = (7, 1, 1, "final", 0) import pypy From pypy.commits at gmail.com Thu Apr 11 08:44:33 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 05:44:33 -0700 (PDT) Subject: [pypy-commit] pypy release-pypy2.7-v7.x: merge default into release Message-ID: <5caf36b1.1c69fb81.964a1.afb6@mx.google.com> Author: Matti Picus Branch: release-pypy2.7-v7.x Changeset: r96447:e2f718f140a3 Date: 2019-04-11 12:41 +0300 http://bitbucket.org/pypy/pypy/changeset/e2f718f140a3/ Log: merge default into release diff too long, truncating to 2000 out of 7687 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -67,3 +67,11 @@ 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 +990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 +bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 +bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 +6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 +6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 +7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 +7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 +de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -113,10 +114,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -141,18 +146,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -260,7 +268,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -387,7 +396,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -423,13 +433,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -451,8 +463,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -512,11 +526,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -592,7 +608,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -616,7 +633,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -634,7 +652,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -658,18 +677,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -688,7 +710,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -913,10 +936,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -951,11 +978,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1012,17 +1042,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1280,7 +1316,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py --- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py +++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py @@ -130,6 +130,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -269,12 +299,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py --- a/extra_tests/cffi_tests/cffi0/test_function.py +++ b/extra_tests/cffi_tests/cffi0/test_function.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -91,7 +92,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -467,3 +467,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * @@ -21,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -590,7 +592,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +651,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1468,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1539,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2106,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py --- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py +++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -86,9 +87,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -187,10 +188,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -213,18 +218,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -325,7 +333,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -446,7 +455,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -479,13 +489,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -503,8 +515,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -556,11 +570,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -626,7 +642,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -649,7 +666,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -665,7 +683,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -686,17 +705,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -714,7 +736,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -923,10 +946,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -948,11 +975,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1001,17 +1031,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1236,7 +1272,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1753,7 +1790,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -1,6 +1,7 @@ # Generated by pypy/tool/import_cffi.py import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from extra_tests.cffi_tests.udir import udir @@ -189,20 +190,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -248,7 +255,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -264,7 +272,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -316,8 +325,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -388,8 +399,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -399,8 +412,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1021,8 +1036,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1035,7 +1052,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1044,8 +1062,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1055,7 +1075,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1065,8 +1086,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1339,7 +1362,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -23,7 +24,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error @@ -572,7 +574,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +633,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1438,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1509,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2201,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -173,7 +173,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -290,7 +290,11 @@ else: bo = byteorder[sys.byteorder] flds = [] + cum_size = 0 for name, obj in typ._fields_: + padding = typ._ffistruct_.fieldoffset(name) - cum_size + if padding: + flds.append('%dx' % padding) # Trim off the leading '<' or '>' ch = get_format_str(obj)[1:] if (ch) == 'B': @@ -301,6 +305,7 @@ flds.append(':') flds.append(name) flds.append(':') + cum_size += typ._ffistruct_.fieldsize(name) return 'T{' + ''.join(flds) + '}' elif hasattr(typ, '_type_'): ch = typ._type_ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -482,6 +482,18 @@ * SyntaxError_ s try harder to give details about the cause of the failure, so the error messages are not the same as in CPython +* Dictionaries and sets are ordered on PyPy. On CPython < 3.6 they are not; + on CPython >= 3.6 dictionaries (but not sets) are ordered. + +* PyPy2 refuses to load lone ``.pyc`` files, i.e. ``.pyc`` files that are + still there after you deleted the ``.py`` file. PyPy3 instead behaves like + CPython. We could be amenable to fix this difference in PyPy2: the current + version reflects `our annoyance`__ with this detail of CPython, which bit + us too often while developing PyPy. (It is as easy as passing the + ``--lonepycfile`` flag when translating PyPy, if you really need it.) + +.. __: https://stackoverflow.com/a/55499713/1556290 + .. _extension-modules: diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -40,11 +40,11 @@ $ hg up -r default $ # edit the version to e.g. 7.0.0-final $ hg ci - $ hg branch release-pypy2.7-7.x && hg ci + $ hg branch release-pypy2.7-v7.x && hg ci $ hg up -r default $ # edit the version to 7.1.0-alpha0 $ hg ci - $ hg up -r release-pypy2.7-7.x + $ hg up -r release-pypy2.7-v7.x $ hg merge default $ # edit the version to AGAIN 7.0.0-final $ hg ci @@ -53,11 +53,11 @@ $ hg up -r py3.5 $ hg merge default # this brings the version fo 7.1.0-alpha0 - $ hg branch release-pypy3.5-7.x + $ hg branch release-pypy3.5-v7.x $ # edit the version to 7.0.0-final $ hg ci $ hg up -r py3.5 - $ hg merge release-pypy3.5-7.x + $ hg merge release-pypy3.5-v7.x $ # edit the version to 7.1.0-alpha0 $ hg ci @@ -109,9 +109,11 @@ * add a tag on the pypy/jitviewer repo that corresponds to pypy release, so that the source tarball can be produced in the next steps - * download the builds, repackage binaries. Tag the release version - and download and repackage source from bitbucket. You may find it - convenient to use the ``repackage.sh`` script in pypy/tool/release to do this. + * download the builds, repackage binaries. Tag the release-candidate version + (it is important to mark this as a candidate since usually at least two + tries are needed to complete the process) and download and repackage source + from bitbucket. You may find it convenient to use the ``repackage.sh`` + script in pypy/tool/release to do this. Otherwise repackage and upload source "-src.tar.bz2" to bitbucket and to cobra, as some packagers prefer a clearly labeled source package @@ -135,3 +137,5 @@ * add a tag on the codespeed web site that corresponds to pypy release * revise versioning at https://readthedocs.org/projects/pypy + * tag the final release(s) with appropriate tags + diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -5,7 +5,7 @@ ---------------- We are happy to discuss ideas around the PyPy ecosystem. -If you are interested in palying with RPython or PyPy, or have a new idea not +If you are interested in playing with RPython or PyPy, or have a new idea not mentioned here please join us on irc, channel #pypy (freenode). If you are unsure, but still think that you can make a valuable contribution to PyPy, dont hesitate to contact us on #pypy or on our mailing list. Here are some ideas diff --git a/pypy/doc/release-v7.1.0.rst b/pypy/doc/release-v7.1.0.rst --- a/pypy/doc/release-v7.1.0.rst +++ b/pypy/doc/release-v7.1.0.rst @@ -24,6 +24,10 @@ Until we can work with downstream providers to distribute builds with PyPy, we have made packages for some common packages `available as wheels`_. +The `CFFI`_ backend has been updated to version 1.12.2. We recommend using CFFI +rather than c-extensions to interact with C, and `cppyy`_ for interacting with +C++ code. + As always, this release is 100% compatible with the previous one and fixed several issues and bugs raised by the growing community of PyPy users. We strongly recommend updating. @@ -31,7 +35,7 @@ The PyPy3.6 release is still not production quality so your mileage may vary. There are open issues with incomplete compatibility and c-extension support. -You can download the v7.0 releases here: +You can download the v7.1 releases here: http://pypy.org/download.html @@ -47,7 +51,7 @@ .. _`PyPy`: index.html .. _`RPython`: https://rpython.readthedocs.org .. _`help`: project-ideas.html -.. _`cffi`: http://cffi.readthedocs.io +.. _`CFFI`: http://cffi.readthedocs.io .. _`cppyy`: https://cppyy.readthedocs.io .. _`available as wheels`: https://github.com/antocuni/pypy-wheels @@ -61,7 +65,7 @@ We also welcome developers of other `dynamic languages`_ to see what RPython can do for them. -The PyPy release supports: +This PyPy release supports: * **x86** machines on most common operating systems (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) @@ -71,7 +75,8 @@ * **s390x** running Linux Unfortunately at the moment of writing our ARM buildbots are out of service, -so for now we are **not** releasing any binary for the ARM architecture. +so for now we are **not** releasing any binary for the ARM architecture, +although PyPy does support ARM 32 bit processors. .. _`PyPy and CPython 2.7.x`: http://speed.pypy.org .. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html @@ -80,5 +85,37 @@ Changelog ========= -If not specified, the changes are shared across versions +Changes shared across versions +* Use utf8 internally to represent unicode, with the goal of never using + rpython-level unicode +* Update ``cffi`` to 1.12.2 +* Improve performance of ``long`` operations where one of the operands fits + into an ``int`` +* Since _ctypes is implemented in pure python over libffi, add interfaces and + methods to support the buffer interface from python. Specifically, add a + ``__pypy__.newmemoryview`` function to create a memoryview and extend the use + of the PyPy-specific ``__buffer__`` class method. This enables better + buffer sharing between ctypes and NumPy. +* Add copying to zlib +* Improve register allocation in the JIT by using better heuristics +* Include ```` on Gnu/Hurd +* Mostly for completeness sake: support for ``rlib.jit.promote_unicode``, which + behaves like ``promote_string``, but for rpython unicode objects +* Correctly initialize the ``d_type`` and ``d_name`` members of builtin + descriptors to fix a segfault related to classmethods in Cython +* Expand documentation of ``__pypy_`` module + +C-API (cpyext) improvements shared across versions + +* Move PyTuple_Type.tp_new to C +* Call internal methods from ``PyDict_XXXItem()`` instead of going through + dunder methods (CPython cpyext compatibility) + +Python 3.6 only + +* Support for os.PathLike in the posix module +* Update ``idellib`` for 3.6.1 +* Make ``BUILD_CONST_KEY_MAP`` JIT-friendly +* Adapt code that optimizes ``sys.exc_info()`` to wordcode +* Fix annotation bug found by ``attrs`` diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -3,5 +3,12 @@ ========================== .. this is a revision shortly after release-pypy-7.1.0 -.. startrev: 78914a03cf95 +.. startrev: d3aefbf6dae7 +.. branch: Twirrim/minor-typo-fix-1553456951526 + +Fix typo + +.. branch: jit-cleanup + +Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -19,6 +19,7 @@ symbols = symtable.SymtableBuilder(space, module, info) return TopLevelCodeGenerator(space, module, symbols, info).assemble() +MAX_STACKDEPTH_CONTAINERS = 100 name_ops_default = misc.dict_to_switch({ ast.Load: ops.LOAD_NAME, @@ -911,6 +912,20 @@ elt_count = len(tup.elts) if tup.elts is not None else 0 if tup.ctx == ast.Store: self.emit_op_arg(ops.UNPACK_SEQUENCE, elt_count) + if tup.ctx == ast.Load and elt_count > MAX_STACKDEPTH_CONTAINERS: + # we need a complete hack to build a new tuple from the list + # ().__class__(l) + empty_index = self.add_const(self.space.newtuple([])) + self.emit_op_arg(ops.LOAD_CONST, empty_index) + self.emit_op_name(ops.LOAD_ATTR, self.names, '__class__') + + self.emit_op_arg(ops.BUILD_LIST, 0) + for element in tup.elts: + element.walkabout(self) + self.emit_op_arg(ops.LIST_APPEND, 1) + + self.emit_op_arg(ops.CALL_FUNCTION, 1) + return self.visit_sequence(tup.elts) if tup.ctx == ast.Load: self.emit_op_arg(ops.BUILD_TUPLE, elt_count) @@ -920,9 +935,17 @@ elt_count = len(l.elts) if l.elts is not None else 0 if l.ctx == ast.Store: self.emit_op_arg(ops.UNPACK_SEQUENCE, elt_count) - self.visit_sequence(l.elts) - if l.ctx == ast.Load: - self.emit_op_arg(ops.BUILD_LIST, elt_count) + if elt_count > MAX_STACKDEPTH_CONTAINERS and l.ctx == ast.Load: + # pushing all the elements would make the stack depth gigantic. + # build the list incrementally instead + self.emit_op_arg(ops.BUILD_LIST, 0) + for element in l.elts: + element.walkabout(self) + self.emit_op_arg(ops.LIST_APPEND, 1) + else: + self.visit_sequence(l.elts) + if l.ctx == ast.Load: + self.emit_op_arg(ops.BUILD_LIST, elt_count) def visit_Dict(self, d): self.update_position(d.lineno) @@ -936,8 +959,15 @@ def visit_Set(self, s): self.update_position(s.lineno) elt_count = len(s.elts) if s.elts is not None else 0 - self.visit_sequence(s.elts) - self.emit_op_arg(ops.BUILD_SET, elt_count) + if elt_count > MAX_STACKDEPTH_CONTAINERS: + self.emit_op_arg(ops.BUILD_SET, 0) + for element in s.elts: + element.walkabout(self) + self.emit_op_arg(ops.SET_ADD, 1) + else: + self.visit_sequence(s.elts) + self.emit_op_arg(ops.BUILD_SET, elt_count) + def visit_Name(self, name): self.update_position(name.lineno) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1218,3 +1218,40 @@ counts = self.count_instructions(source) assert ops.BUILD_TUPLE not in counts + +class TestHugeStackDepths: + def run_and_check_stacksize(self, source): + space = self.space + code = compile_with_astcompiler("a = " + source, 'exec', space) + assert code.co_stacksize < 100 + w_dict = space.newdict() + code.exec_code(space, w_dict, w_dict) + return space.getitem(w_dict, space.newtext("a")) + + def test_tuple(self): + source = "(" + ",".join([str(i) for i in range(200)]) + ")\n" + w_res = self.run_and_check_stacksize(source) + assert self.space.unwrap(w_res) == tuple(range(200)) + + def test_list(self): + source = "a = [" + ",".join([str(i) for i in range(200)]) + "]\n" + w_res = self.run_and_check_stacksize(source) + assert self.space.unwrap(w_res) == range(200) + + def test_list_unpacking(self): + space = self.space + source = "[" + ",".join(['b%d' % i for i in range(200)]) + "] = a\n" + code = compile_with_astcompiler(source, 'exec', space) + assert code.co_stacksize == 200 # xxx remains big + w_dict = space.newdict() + space.setitem(w_dict, space.newtext("a"), space.wrap(range(42, 242))) + code.exec_code(space, w_dict, w_dict) + assert space.unwrap(space.getitem(w_dict, space.newtext("b0"))) == 42 + assert space.unwrap(space.getitem(w_dict, space.newtext("b199"))) == 241 + + def test_set(self): + source = "a = {" + ",".join([str(i) for i in range(200)]) + "}\n" + w_res = self.run_and_check_stacksize(source) + space = self.space + assert [space.int_w(w_x) + for w_x in space.unpackiterable(w_res)] == range(200) diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -537,14 +537,17 @@ def wcharpsize2utf8(space, wcharp, size): """Safe version of rffi.wcharpsize2utf8. - Raises app-level rutf8.OutOfRange if any wchar value is outside the valid + Raises app-level ValueError if any wchar value is outside the valid codepoint range. """ try: return rffi.wcharpsize2utf8(wcharp, size) except rutf8.OutOfRange as e: - raise oefmt(space.w_ValueError, - "character %s is not in range [U+0000; U+10ffff]", 'U+%x' % e.code) + raise wrap_unicode_out_of_range_error(space, e) + +def wrap_unicode_out_of_range_error(space, e): + raise oefmt(space.w_ValueError, + "character %s is not in range [U+0000; U+10ffff]", 'U+%x' % e.code) # ____________________________________________________________ diff --git a/pypy/module/__pypy__/interp_builders.py b/pypy/module/__pypy__/interp_builders.py --- a/pypy/module/__pypy__/interp_builders.py +++ b/pypy/module/__pypy__/interp_builders.py @@ -65,9 +65,12 @@ return W_UnicodeBuilder(space, 3 * size) def descr_append(self, space, w_s): - w_unicode = W_UnicodeObject.convert_arg_to_w_unicode(space, w_s) - s = space.utf8_w(w_unicode) - self.builder.append(s) + if isinstance(w_s, W_UnicodeObject): + self.builder.append_utf8(w_s._utf8, w_s._len()) + else: + w_unicode = W_UnicodeObject.convert_arg_to_w_unicode(space, w_s) + s = space.utf8_w(w_unicode) + self.builder.append(s) @unwrap_spec(start=int, end=int) def descr_append_slice(self, space, w_s, start, end): diff --git a/pypy/module/__pypy__/test/test_builders.py b/pypy/module/__pypy__/test/test_builders.py --- a/pypy/module/__pypy__/test/test_builders.py +++ b/pypy/module/__pypy__/test/test_builders.py @@ -1,14 +1,16 @@ +# -*- encoding: utf-8 -*- + class AppTestBuilders(object): spaceconfig = dict(usemodules=['__pypy__']) def test_simple(self): from __pypy__.builders import UnicodeBuilder b = UnicodeBuilder() - b.append(u"abc") + b.append(u"abcä") b.append(u"123") b.append(u"1") s = b.build() - assert s == u"abc1231" + assert s == u"abcä1231" assert type(s) is unicode assert b.build() == s b.append(u"123") diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -401,15 +401,22 @@ # bypass the method 'string' implemented in W_CTypePrimitive return W_CType.string(self, cdataobj, maxlen) - def convert_to_object(self, cdata): - space = self.space + def _read_bool_0_or_1(self, cdata): + """Read one byte, check it is 0 or 1, but return it as an integer""" value = ord(cdata[0]) - if value < 2: - return space.newbool(value != 0) - else: - raise oefmt(space.w_ValueError, + if value >= 2: + raise oefmt(self.space.w_ValueError, "got a _Bool of value %d, expected 0 or 1", value) + return value + + def convert_to_object(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newbool(value != 0) + + def cast_to_int(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newint(value) def unpack_list_of_int_items(self, ptr, length): return None diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -304,8 +304,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -433,7 +435,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -526,13 +529,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -547,10 +553,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -598,10 +608,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -614,8 +628,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -766,10 +782,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -781,30 +799,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1625,7 +1654,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1755,14 +1785,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1771,7 +1804,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1831,14 +1865,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2170,8 +2207,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): + s.a1 = b'a' + with pytest.raises(TypeError): + s.a1 = bytechr(0xFF) s.a1 = u+'\u1234' assert s.a1 == u+'\u1234' if pyuni4: @@ -2185,7 +2224,8 @@ s.a1 = u+'\ud807\udf44' assert s.a1 == u+'\U00011f44' else: - py.test.raises(TypeError, "s.a1 = u+'\U00012345'") + with pytest.raises(TypeError): + s.a1 = u+'\U00012345' # BWCharArray = new_array_type(BWCharP, None) a = newp(BWCharArray, u+'hello \u1234 world') @@ -2209,7 +2249,8 @@ assert list(a) == expected got = [a[i] for i in range(4)] assert got == expected - py.test.raises(IndexError, 'a[4]') + with pytest.raises(IndexError): + a[4] # w = cast(BWChar, 'a') assert repr(w) == "" % (typename, mandatory_u_prefix) @@ -2341,9 +2382,11 @@ def test_cannot_dereference_void(): BVoidP = new_pointer_type(new_void_type()) p = cast(BVoidP, 123456) - py.test.raises(TypeError, "p[0]") + with pytest.raises(TypeError): + p[0] p = cast(BVoidP, 0) - py.test.raises((TypeError, RuntimeError), "p[0]") + with pytest.raises((TypeError, RuntimeError)): + p[0] def test_iter(): BInt = new_primitive_type("int") @@ -2366,12 +2409,12 @@ assert (q == p) is False assert (q != p) is True if strict_compare: - py.test.raises(TypeError, "p < q") - py.test.raises(TypeError, "p <= q") - py.test.raises(TypeError, "q < p") - py.test.raises(TypeError, "q <= p") - py.test.raises(TypeError, "p > q") - py.test.raises(TypeError, "p >= q") + with pytest.raises(TypeError): p < q + with pytest.raises(TypeError): p <= q + with pytest.raises(TypeError): q < p + with pytest.raises(TypeError): q <= p + with pytest.raises(TypeError): p > q + with pytest.raises(TypeError): p >= q r = cast(BVoidP, p) assert (p < r) is False assert (p <= r) is True @@ -2417,7 +2460,8 @@ try: expected = b"hi there\x00"[i] except IndexError: - py.test.raises(IndexError, "buf[i]") + with pytest.raises(IndexError): + buf[i] else: assert buf[i] == bitem2bchr(expected) # --mb_slice-- @@ -2444,15 +2488,18 @@ try: expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + with pytest.raises(IndexError): + buf[i] = bytechr(i & 0xff) else: buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) - py.test.raises(ValueError, 'buf[:] = b"shorter"') - py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + with pytest.raises(ValueError): + buf[:] = b"shorter" + with pytest.raises(ValueError): + buf[:] = b"this is much too long!" buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" buf[:2] = b"HI" @@ -2526,14 +2573,16 @@ BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) x = newp(BCharP) - py.test.raises(TypeError, "del x[0]") + with pytest.raises(TypeError): + del x[0] def test_bug_delattr(): BLong = new_primitive_type("long") BStruct = new_struct_type("struct foo") complete_struct_or_union(BStruct, [('a1', BLong, -1)]) x = newp(new_pointer_type(BStruct)) - py.test.raises(AttributeError, "del x.a1") + with pytest.raises(AttributeError): + del x.a1 def test_variable_length_struct(): py.test.skip("later") @@ -2551,7 +2600,8 @@ assert sizeof(x) == 6 * size_of_long() x[4] = 123 assert x[4] == 123 - py.test.raises(IndexError, "x[5]") + with pytest.raises(IndexError): + x[5] assert len(x.a2) == 5 # py.test.raises(TypeError, newp, BStructP, [123]) @@ -2803,7 +2853,8 @@ BCharP = new_pointer_type(new_primitive_type("char")) p = newp(BCharP, b'X') q = cast(BBoolP, p) - py.test.raises(ValueError, "q[0]") + with pytest.raises(ValueError): + q[0] py.test.raises(TypeError, newp, BBoolP, b'\x00') assert newp(BBoolP, 0)[0] is False assert newp(BBoolP, 1)[0] is True @@ -3103,8 +3154,10 @@ assert c[1] == 123 assert c[3] == 456 assert d[2] == 456 - py.test.raises(IndexError, "d[3]") - py.test.raises(IndexError, "d[-1]") + with pytest.raises(IndexError): + d[3] + with pytest.raises(IndexError): + d[-1] def test_slice_ptr(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -3122,7 +3175,8 @@ c = newp(BIntArray, 5) c[0:5] assert len(c[5:5]) == 0 - py.test.raises(IndexError, "c[-1:1]") + with pytest.raises(IndexError): + c[-1:1] cp = c + 0 cp[-1:1] @@ -3130,17 +3184,23 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) - e = py.test.raises(IndexError, "c[:5]") + with pytest.raises(IndexError) as e: + c[:5] assert str(e.value) == "slice start must be specified" - e = py.test.raises(IndexError, "c[4:]") + with pytest.raises(IndexError) as e: + c[4:] assert str(e.value) == "slice stop must be specified" - e = py.test.raises(IndexError, "c[1:2:3]") + with pytest.raises(IndexError) as e: + c[1:2:3] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[1:2:1]") + with pytest.raises(IndexError) as e: + c[1:2:1] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[4:2]") + with pytest.raises(IndexError) as e: + c[4:2] assert str(e.value) == "slice start > stop" - e = py.test.raises(IndexError, "c[6:6]") + with pytest.raises(IndexError) as e: + c[6:6] assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): From pypy.commits at gmail.com Thu Apr 11 08:45:07 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 05:45:07 -0700 (PDT) Subject: [pypy-commit] pypy release-pypy3.6-v7.x: merge py3.6 into release Message-ID: <5caf36d3.1c69fb81.2f0d3.9ada@mx.google.com> Author: Matti Picus Branch: release-pypy3.6-v7.x Changeset: r96449:8d8e54ef864e Date: 2019-04-11 14:36 +0300 http://bitbucket.org/pypy/pypy/changeset/8d8e54ef864e/ Log: merge py3.6 into release diff too long, truncating to 2000 out of 8030 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -67,3 +67,11 @@ 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 +990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 +bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 +bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 +6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 +6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 +7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 +7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 +de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -113,10 +114,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -141,18 +146,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -260,7 +268,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -387,7 +396,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -423,13 +433,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -451,8 +463,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -512,11 +526,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -592,7 +608,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -616,7 +633,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -634,7 +652,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -658,18 +677,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -688,7 +710,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -913,10 +936,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -951,11 +978,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1012,17 +1042,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1280,7 +1316,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py --- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py +++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py @@ -130,6 +130,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -269,12 +299,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py --- a/extra_tests/cffi_tests/cffi0/test_function.py +++ b/extra_tests/cffi_tests/cffi0/test_function.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -91,7 +92,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -467,3 +467,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * @@ -21,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -590,7 +592,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +651,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1468,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1539,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2106,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py --- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py +++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -86,9 +87,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -187,10 +188,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -213,18 +218,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -325,7 +333,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -446,7 +455,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -479,13 +489,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -503,8 +515,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -556,11 +570,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -626,7 +642,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -649,7 +666,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -665,7 +683,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -686,17 +705,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -714,7 +736,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -923,10 +946,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -948,11 +975,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1001,17 +1031,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1236,7 +1272,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1753,7 +1790,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -1,6 +1,7 @@ # Generated by pypy/tool/import_cffi.py import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from extra_tests.cffi_tests.udir import udir @@ -189,20 +190,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -248,7 +255,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -264,7 +272,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -316,8 +325,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -388,8 +399,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -399,8 +412,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1021,8 +1036,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1035,7 +1052,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1044,8 +1062,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1055,7 +1075,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1065,8 +1086,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1339,7 +1362,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -23,7 +24,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error @@ -572,7 +574,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +633,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1438,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1509,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2201,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -173,7 +173,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -296,7 +296,11 @@ else: bo = byteorder[sys.byteorder] flds = [] + cum_size = 0 for name, obj in typ._fields_: + padding = typ._ffistruct_.fieldoffset(name) - cum_size + if padding: + flds.append('%dx' % padding) # Trim off the leading '<' or '>' ch = get_format_str(obj)[1:] if (ch) == 'B': @@ -307,6 +311,7 @@ flds.append(':') flds.append(name) flds.append(':') + cum_size += typ._ffistruct_.fieldsize(name) return 'T{' + ''.join(flds) + '}' elif hasattr(typ, '_type_'): ch = typ._type_ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -495,6 +495,18 @@ * SyntaxError_ s try harder to give details about the cause of the failure, so the error messages are not the same as in CPython +* Dictionaries and sets are ordered on PyPy. On CPython < 3.6 they are not; + on CPython >= 3.6 dictionaries (but not sets) are ordered. + +* PyPy2 refuses to load lone ``.pyc`` files, i.e. ``.pyc`` files that are + still there after you deleted the ``.py`` file. PyPy3 instead behaves like + CPython. We could be amenable to fix this difference in PyPy2: the current + version reflects `our annoyance`__ with this detail of CPython, which bit + us too often while developing PyPy. (It is as easy as passing the + ``--lonepycfile`` flag when translating PyPy, if you really need it.) + +.. __: https://stackoverflow.com/a/55499713/1556290 + .. _extension-modules: diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -40,11 +40,11 @@ $ hg up -r default $ # edit the version to e.g. 7.0.0-final $ hg ci - $ hg branch release-pypy2.7-7.x && hg ci + $ hg branch release-pypy2.7-v7.x && hg ci $ hg up -r default $ # edit the version to 7.1.0-alpha0 $ hg ci - $ hg up -r release-pypy2.7-7.x + $ hg up -r release-pypy2.7-v7.x $ hg merge default $ # edit the version to AGAIN 7.0.0-final $ hg ci @@ -53,11 +53,11 @@ $ hg up -r py3.5 $ hg merge default # this brings the version fo 7.1.0-alpha0 - $ hg branch release-pypy3.5-7.x + $ hg branch release-pypy3.5-v7.x $ # edit the version to 7.0.0-final $ hg ci $ hg up -r py3.5 - $ hg merge release-pypy3.5-7.x + $ hg merge release-pypy3.5-v7.x $ # edit the version to 7.1.0-alpha0 $ hg ci @@ -109,9 +109,11 @@ * add a tag on the pypy/jitviewer repo that corresponds to pypy release, so that the source tarball can be produced in the next steps - * download the builds, repackage binaries. Tag the release version - and download and repackage source from bitbucket. You may find it - convenient to use the ``repackage.sh`` script in pypy/tool/release to do this. + * download the builds, repackage binaries. Tag the release-candidate version + (it is important to mark this as a candidate since usually at least two + tries are needed to complete the process) and download and repackage source + from bitbucket. You may find it convenient to use the ``repackage.sh`` + script in pypy/tool/release to do this. Otherwise repackage and upload source "-src.tar.bz2" to bitbucket and to cobra, as some packagers prefer a clearly labeled source package @@ -135,3 +137,5 @@ * add a tag on the codespeed web site that corresponds to pypy release * revise versioning at https://readthedocs.org/projects/pypy + * tag the final release(s) with appropriate tags + diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -5,7 +5,7 @@ ---------------- We are happy to discuss ideas around the PyPy ecosystem. -If you are interested in palying with RPython or PyPy, or have a new idea not +If you are interested in playing with RPython or PyPy, or have a new idea not mentioned here please join us on irc, channel #pypy (freenode). If you are unsure, but still think that you can make a valuable contribution to PyPy, dont hesitate to contact us on #pypy or on our mailing list. Here are some ideas diff --git a/pypy/doc/release-v7.1.0.rst b/pypy/doc/release-v7.1.0.rst --- a/pypy/doc/release-v7.1.0.rst +++ b/pypy/doc/release-v7.1.0.rst @@ -24,6 +24,10 @@ Until we can work with downstream providers to distribute builds with PyPy, we have made packages for some common packages `available as wheels`_. +The `CFFI`_ backend has been updated to version 1.12.2. We recommend using CFFI +rather than c-extensions to interact with C, and `cppyy`_ for interacting with +C++ code. + As always, this release is 100% compatible with the previous one and fixed several issues and bugs raised by the growing community of PyPy users. We strongly recommend updating. @@ -31,7 +35,7 @@ The PyPy3.6 release is still not production quality so your mileage may vary. There are open issues with incomplete compatibility and c-extension support. -You can download the v7.0 releases here: +You can download the v7.1 releases here: http://pypy.org/download.html @@ -47,7 +51,7 @@ .. _`PyPy`: index.html .. _`RPython`: https://rpython.readthedocs.org .. _`help`: project-ideas.html -.. _`cffi`: http://cffi.readthedocs.io +.. _`CFFI`: http://cffi.readthedocs.io .. _`cppyy`: https://cppyy.readthedocs.io .. _`available as wheels`: https://github.com/antocuni/pypy-wheels @@ -61,7 +65,7 @@ We also welcome developers of other `dynamic languages`_ to see what RPython can do for them. -The PyPy release supports: +This PyPy release supports: * **x86** machines on most common operating systems (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) @@ -71,7 +75,8 @@ * **s390x** running Linux Unfortunately at the moment of writing our ARM buildbots are out of service, -so for now we are **not** releasing any binary for the ARM architecture. +so for now we are **not** releasing any binary for the ARM architecture, +although PyPy does support ARM 32 bit processors. .. _`PyPy and CPython 2.7.x`: http://speed.pypy.org .. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html @@ -80,5 +85,37 @@ Changelog ========= -If not specified, the changes are shared across versions +Changes shared across versions +* Use utf8 internally to represent unicode, with the goal of never using + rpython-level unicode +* Update ``cffi`` to 1.12.2 +* Improve performance of ``long`` operations where one of the operands fits + into an ``int`` +* Since _ctypes is implemented in pure python over libffi, add interfaces and + methods to support the buffer interface from python. Specifically, add a + ``__pypy__.newmemoryview`` function to create a memoryview and extend the use + of the PyPy-specific ``__buffer__`` class method. This enables better + buffer sharing between ctypes and NumPy. +* Add copying to zlib +* Improve register allocation in the JIT by using better heuristics +* Include ```` on Gnu/Hurd +* Mostly for completeness sake: support for ``rlib.jit.promote_unicode``, which + behaves like ``promote_string``, but for rpython unicode objects +* Correctly initialize the ``d_type`` and ``d_name`` members of builtin + descriptors to fix a segfault related to classmethods in Cython +* Expand documentation of ``__pypy_`` module + +C-API (cpyext) improvements shared across versions + +* Move PyTuple_Type.tp_new to C +* Call internal methods from ``PyDict_XXXItem()`` instead of going through + dunder methods (CPython cpyext compatibility) + +Python 3.6 only + +* Support for os.PathLike in the posix module +* Update ``idellib`` for 3.6.1 +* Make ``BUILD_CONST_KEY_MAP`` JIT-friendly +* Adapt code that optimizes ``sys.exc_info()`` to wordcode +* Fix annotation bug found by ``attrs`` diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -3,4 +3,12 @@ ========================== .. this is a revision shortly after release-pypy-7.1.0 -.. startrev: 78914a03cf95 +.. startrev: d3aefbf6dae7 + +.. branch: Twirrim/minor-typo-fix-1553456951526 + +Fix typo + +.. branch: jit-cleanup + +Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -21,6 +21,7 @@ symbols = symtable.SymtableBuilder(space, module, info) return TopLevelCodeGenerator(space, module, symbols, info).assemble() +MAX_STACKDEPTH_CONTAINERS = 100 name_ops_default = misc.dict_to_switch({ ast.Load: ops.LOAD_NAME, @@ -922,6 +923,9 @@ values_count = len(values) if targets_count != values_count: return False + for value in values: + if isinstance(value, ast.Starred): + return False # more complicated for target in targets: if not isinstance(target, ast.Name): if isinstance(target, ast.Starred): @@ -1222,8 +1226,29 @@ ifexp.orelse.walkabout(self) self.use_next_block(end) - def _visit_starunpack(self, node, elts, single_op, inner_op, outer_op): + def _visit_starunpack(self, node, elts, single_op, inner_op, outer_op, add_op): elt_count = len(elts) if elts else 0 + contains_starred = False + for i in range(elt_count): + elt = elts[i] + if isinstance(elt, ast.Starred): + contains_starred = True + break + if elt_count > MAX_STACKDEPTH_CONTAINERS and not contains_starred: + tuplecase = False + if add_op == -1: # tuples + self.emit_op_arg(ops.BUILD_LIST, 0) + add_op = ops.LIST_APPEND + tuplecase = True + else: + self.emit_op_arg(single_op, 0) + for elt in elts: + elt.walkabout(self) + self.emit_op_arg(add_op, 1) + if tuplecase: + self.emit_op_arg(ops.BUILD_TUPLE_UNPACK, 1) + return + seen_star = 0 elt_subitems = 0 for i in range(elt_count): @@ -1279,7 +1304,7 @@ if tup.ctx == ast.Store: self._visit_assignment(tup, tup.elts, tup.ctx) elif tup.ctx == ast.Load: - self._visit_starunpack(tup, tup.elts, ops.BUILD_TUPLE, ops.BUILD_TUPLE, ops.BUILD_TUPLE_UNPACK) + self._visit_starunpack(tup, tup.elts, ops.BUILD_TUPLE, ops.BUILD_TUPLE, ops.BUILD_TUPLE_UNPACK, -1) else: self.visit_sequence(tup.elts) @@ -1288,7 +1313,8 @@ if l.ctx == ast.Store: self._visit_assignment(l, l.elts, l.ctx) elif l.ctx == ast.Load: - self._visit_starunpack(l, l.elts, ops.BUILD_LIST, ops.BUILD_TUPLE, ops.BUILD_LIST_UNPACK) + self._visit_starunpack( + l, l.elts, ops.BUILD_LIST, ops.BUILD_TUPLE, ops.BUILD_LIST_UNPACK, ops.LIST_APPEND) else: self.visit_sequence(l.elts) @@ -1299,6 +1325,21 @@ is_unpacking = False all_constant_keys_w = None if d.values: + unpacking_anywhere = False + for key in d.keys: + if key is None: + unpacking_anywhere = True + break + if not unpacking_anywhere and len(d.keys) > MAX_STACKDEPTH_CONTAINERS: + # do it in a small amount of stack + self.emit_op_arg(ops.BUILD_MAP, 0) + for i in range(len(d.values)): + d.values[i].walkabout(self) + key = d.keys[i] + assert key is not None + key.walkabout(self) + self.emit_op_arg(ops.MAP_ADD, 1) + return if len(d.keys) < 0xffff: all_constant_keys_w = [] for key in d.keys: @@ -1343,7 +1384,7 @@ is_unpacking = False def visit_Set(self, s): - self._visit_starunpack(s, s.elts, ops.BUILD_SET, ops.BUILD_SET, ops.BUILD_SET_UNPACK) + self._visit_starunpack(s, s.elts, ops.BUILD_SET, ops.BUILD_SET, ops.BUILD_SET_UNPACK, ops.SET_ADD) def visit_Name(self, name): self.update_position(name.lineno) diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py --- a/pypy/interpreter/astcompiler/optimize.py +++ b/pypy/interpreter/astcompiler/optimize.py @@ -302,6 +302,9 @@ node = tup.elts[i] w_const = node.as_constant() if w_const is None: + new_elts = self._optimize_constant_star_unpacks(tup.elts) + if new_elts is not None: + return ast.Tuple(new_elts, ast.Load, tup.lineno, tup.col_offset) return tup consts_w[i] = w_const # intern the string constants packed into the tuple here, @@ -314,6 +317,62 @@ w_consts = self.space.newtuple(consts_w) return ast.Constant(w_consts, tup.lineno, tup.col_offset) + def _make_starred_tuple_const(self, consts_w, firstelt): + w_consts = self.space.newtuple(consts_w[:]) + return ast.Starred(ast.Constant( + w_consts, firstelt.lineno, firstelt.col_offset), + ast.Load, firstelt.lineno, firstelt.col_offset) + + def _optimize_constant_star_unpacks(self, elts): + # turn (1, 2, 3, *a) into (*(1, 2, 3), *a) with a constant (1, 2, 3) + # or similarly, for lists + contains_starred = False + for i in range(len(elts)): + elt = elts[i] + if isinstance(elt, ast.Starred): + contains_starred = True + break + if not contains_starred: + return None + new_elts = [] + changed = False + const_since_last_star_w = [] + after_last_star_index = 0 + for i in range(len(elts)): + elt = elts[i] + if isinstance(elt, ast.Starred): + if const_since_last_star_w is not None: + firstelt = elts[after_last_star_index] + new_elts.append(self._make_starred_tuple_const( + const_since_last_star_w, firstelt)) + changed = True + const_since_last_star_w = [] + after_last_star_index = i + 1 + new_elts.append(elt) + elif const_since_last_star_w is not None: + w_const = elt.as_constant() + if w_const is None: + new_elts.extend(elts[after_last_star_index:i + 1]) + const_since_last_star_w = None + else: + const_since_last_star_w.append(w_const) + else: + new_elts.append(elt) + if after_last_star_index != len(elts) and const_since_last_star_w is not None: + firstelt = elts[after_last_star_index] + new_elts.append(self._make_starred_tuple_const( + const_since_last_star_w, firstelt)) + changed = True + if changed: + return new_elts + + def visit_List(self, l): + if l.ctx == ast.Load and l.elts: + new_elts = self._optimize_constant_star_unpacks(l.elts) + if new_elts: + return ast.List(new_elts, ast.Load, l.lineno, l.col_offset) + return l + def visit_Subscript(self, subs): if subs.ctx == ast.Load: w_obj = subs.value.as_constant() diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1099,14 +1099,30 @@ return a, b, c """ yield self.st, func, "f()", (1, [2, 3], 4) + + def test_unpacking_while_building(self): func = """def f(): b = [4,5,6] - c = 7 - a = [*b, c] + a = (*b, 7) + return a + """ + yield self.st, func, "f()", (4, 5, 6, 7) + + func = """def f(): + b = [4,5,6] + a = [*b, 7] return a """ yield self.st, func, "f()", [4, 5, 6, 7] + func = """def f(): + b = [4,] + x, y = (*b, 7) + return x + """ + yield self.st, func, "f()", 4 + + def test_extended_unpacking_fail(self): exc = py.test.raises(SyntaxError, self.simple_test, "*a, *b = [1, 2]", None, None).value @@ -1542,4 +1558,71 @@ counts = self.count_instructions(source) assert ops.BUILD_TUPLE not in counts + def test_constant_tuples_star(self): + source = """def f(a, c): + return (u"a", 1, *a, 3, 5, 3, *c) + """ + counts = self.count_instructions(source) + assert ops.BUILD_TUPLE not in counts + source = """def f(a, c, d): + return (u"a", 1, *a, c, 1, *d, 1, 2, 3) + """ + counts = self.count_instructions(source) + assert counts[ops.BUILD_TUPLE] == 1 + + def test_constant_list_star(self): + source = """def f(a, c): + return [u"a", 1, *a, 3, 5, 3, *c] + """ + counts = self.count_instructions(source) + assert ops.BUILD_TUPLE not in counts + + source = """def f(a, c, d): + return [u"a", 1, *a, c, 1, *d, 1, 2, 3] + """ + counts = self.count_instructions(source) + assert counts[ops.BUILD_TUPLE] == 1 + + +class TestHugeStackDepths: + def run_and_check_stacksize(self, source): + space = self.space + code = compile_with_astcompiler("a = " + source, 'exec', space) + assert code.co_stacksize < 100 + w_dict = space.newdict() + code.exec_code(space, w_dict, w_dict) + return space.getitem(w_dict, space.newtext("a")) + + def test_tuple(self): + source = "(" + ",".join([str(i) for i in range(200)]) + ")\n" + w_res = self.run_and_check_stacksize(source) + assert self.space.unwrap(w_res) == tuple(range(200)) + + def test_list(self): + source = "[" + ",".join([str(i) for i in range(200)]) + "]\n" + w_res = self.run_and_check_stacksize(source) + assert self.space.unwrap(w_res) == range(200) + + def test_list_unpacking(self): + space = self.space + source = "[" + ",".join(['b%d' % i for i in range(200)]) + "] = a\n" + code = compile_with_astcompiler(source, 'exec', space) + assert code.co_stacksize == 200 # xxx remains big + w_dict = space.newdict() + space.setitem(w_dict, space.newtext("a"), space.wrap(range(42, 242))) + code.exec_code(space, w_dict, w_dict) + assert space.unwrap(space.getitem(w_dict, space.newtext("b0"))) == 42 + assert space.unwrap(space.getitem(w_dict, space.newtext("b199"))) == 241 + + def test_set(self): + source = "{" + ",".join([str(i) for i in range(200)]) + "}\n" + w_res = self.run_and_check_stacksize(source) + space = self.space + assert [space.int_w(w_x) + for w_x in space.unpackiterable(w_res)] == range(200) + + def test_dict(self): + source = "{" + ",".join(['%s: None' % (i, ) for i in range(200)]) + "}\n" + w_res = self.run_and_check_stacksize(source) + assert self.space.unwrap(w_res) == dict.fromkeys(range(200)) diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py --- a/pypy/interpreter/astcompiler/test/test_symtable.py +++ b/pypy/interpreter/astcompiler/test/test_symtable.py @@ -456,7 +456,7 @@ scp = self.func_scope("async def f(): pass") assert not scp.is_generator scp = self.func_scope("async def f(): await 5") - assert scp.is_generator + assert not scp.is_generator def test_yield_inside_try(self): scp = self.func_scope("def f(): yield x") diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -662,14 +662,17 @@ def wcharpsize2utf8(space, wcharp, size): """Safe version of rffi.wcharpsize2utf8. - Raises app-level rutf8.OutOfRange if any wchar value is outside the valid + Raises app-level ValueError if any wchar value is outside the valid codepoint range. """ try: return rffi.wcharpsize2utf8(wcharp, size) except rutf8.OutOfRange as e: - raise oefmt(space.w_ValueError, - "character %s is not in range [U+0000; U+10ffff]", 'U+%x' % e.code) + raise wrap_unicode_out_of_range_error(space, e) + +def wrap_unicode_out_of_range_error(space, e): + raise oefmt(space.w_ValueError, + "character %s is not in range [U+0000; U+10ffff]", 'U+%x' % e.code) # ____________________________________________________________ diff --git a/pypy/module/__pypy__/interp_builders.py b/pypy/module/__pypy__/interp_builders.py --- a/pypy/module/__pypy__/interp_builders.py +++ b/pypy/module/__pypy__/interp_builders.py @@ -64,9 +64,12 @@ return W_UnicodeBuilder(space, 3 * size) def descr_append(self, space, w_s): - w_unicode = W_UnicodeObject.convert_arg_to_w_unicode(space, w_s) - s = space.utf8_w(w_unicode) - self.builder.append(s) + if isinstance(w_s, W_UnicodeObject): + self.builder.append_utf8(w_s._utf8, w_s._len()) + else: + w_unicode = W_UnicodeObject.convert_arg_to_w_unicode(space, w_s) + s = space.utf8_w(w_unicode) + self.builder.append(s) @unwrap_spec(start=int, end=int) def descr_append_slice(self, space, w_s, start, end): diff --git a/pypy/module/__pypy__/test/test_builders.py b/pypy/module/__pypy__/test/test_builders.py --- a/pypy/module/__pypy__/test/test_builders.py +++ b/pypy/module/__pypy__/test/test_builders.py @@ -1,14 +1,16 @@ +# -*- encoding: utf-8 -*- + class AppTestBuilders(object): spaceconfig = dict(usemodules=['__pypy__']) def test_simple(self): from __pypy__.builders import StringBuilder b = StringBuilder() - b.append(u"abc") + b.append(u"abcä") b.append(u"123") b.append(u"1") s = b.build() - assert s == u"abc1231" + assert s == u"abcä1231" assert b.build() == s b.append(u"123") assert b.build() == s + u"123" diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -402,15 +402,22 @@ # bypass the method 'string' implemented in W_CTypePrimitive return W_CType.string(self, cdataobj, maxlen) - def convert_to_object(self, cdata): - space = self.space + def _read_bool_0_or_1(self, cdata): + """Read one byte, check it is 0 or 1, but return it as an integer""" value = ord(cdata[0]) - if value < 2: - return space.newbool(value != 0) - else: - raise oefmt(space.w_ValueError, + if value >= 2: + raise oefmt(self.space.w_ValueError, "got a _Bool of value %d, expected 0 or 1", value) + return value + + def convert_to_object(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newbool(value != 0) + + def cast_to_int(self, cdata): + value = self._read_bool_0_or_1(cdata) + return self.space.newint(value) def unpack_list_of_int_items(self, ptr, length): return None diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -304,8 +304,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -433,7 +435,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -526,13 +529,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -547,10 +553,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -598,10 +608,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -614,8 +628,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -766,10 +782,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -781,30 +799,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1625,7 +1654,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1755,14 +1785,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1771,7 +1804,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1831,14 +1865,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2170,8 +2207,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): From pypy.commits at gmail.com Thu Apr 11 08:45:09 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 05:45:09 -0700 (PDT) Subject: [pypy-commit] pypy release-pypy3.6-v7.x: update version to 7.1.1 Message-ID: <5caf36d5.1c69fb81.d7a12.20ad@mx.google.com> Author: Matti Picus Branch: release-pypy3.6-v7.x Changeset: r96450:b881e8541f01 Date: 2019-04-11 14:38 +0300 http://bitbucket.org/pypy/pypy/changeset/b881e8541f01/ Log: update version to 7.1.1 diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -32,8 +32,8 @@ * module/sys/version.py * doc/conf.py */ -#define PYPY_VERSION "7.1.0-beta0" -#define PYPY_VERSION_NUM 0x07010000 +#define PYPY_VERSION "7.1.1-beta0" +#define PYPY_VERSION_NUM 0x07010100 /* Defined to mean a PyPy where cpyext holds more regular references to PyObjects, e.g. staying alive as long as the internal PyPy object stays alive. */ diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -13,7 +13,7 @@ # make sure to keep PYPY_VERSION in sync with: # module/cpyext/include/patchlevel.h # doc/conf.py -PYPY_VERSION = (7, 1, 0, "beta", 0) +PYPY_VERSION = (7, 1, 1, "beta", 0) import pypy From pypy.commits at gmail.com Thu Apr 11 08:45:59 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 11 Apr 2019 05:45:59 -0700 (PDT) Subject: [pypy-commit] pypy default: start release note Message-ID: <5caf3707.1c69fb81.aa5cb.ae8f@mx.google.com> Author: Matti Picus Branch: Changeset: r96451:6e6c42053a2a Date: 2019-04-11 15:38 +0300 http://bitbucket.org/pypy/pypy/changeset/6e6c42053a2a/ Log: start release note diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v7.1.1.rst @@ -0,0 +1,96 @@ +========================================= +PyPy v7.1.1: release of 2.7, and 3.6-beta +========================================= + +The PyPy team is proud to release a bug-fix release version 7.1.1 of PyPy, which +includes two different interpreters: + + - PyPy2.7, which is an interpreter supporting the syntax and the features of + Python 2.7 + + - PyPy3.6-beta: this is the second official release of PyPy to support 3.6 + features, although it is still considered beta quality. + +The interpreters are based on much the same codebase, thus the double +release. + +As always, this release is 100% compatible with the previous one and fixed +several issues and bugs raised by the growing community of PyPy users. +We strongly recommend updating. + +The PyPy3.6 release is still not production quality so your mileage may vary. +There are open issues with incomplete compatibility and c-extension support. + +You can download the v7.1.1 releases here: + + http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project. If PyPy is not quite good enough for your needs, we are available for +direct consulting work. + +We would also like to thank our contributors and encourage new people to join +the project. PyPy has many layers and we need help with all of them: `PyPy`_ +and `RPython`_ documentation improvements, tweaking popular modules to run +on pypy, or general `help`_ with making RPython's JIT even better. + +.. _`PyPy`: index.html +.. _`RPython`: https://rpython.readthedocs.org +.. _`help`: project-ideas.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7, 3.6. It's fast (`PyPy and CPython 2.7.x`_ performance +comparison) due to its integrated tracing JIT compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +This PyPy release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +Unfortunately at the moment of writing our ARM buildbots are out of service, +so for now we are **not** releasing any binary for the ARM architecture, +although PyPy does support ARM 32 bit processors. + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + + +Changelog +========= + +Changes shared across versions +* improve performance of ``u''.append`` +* Prevent a crash in ``zlib`` when flushing a closed stream +* Fix a few corener cases when encountering unicode values above 0x110000 +* Teach the JIT how to handle very large constant lists, sets, or dicts +* Fix building on ARM32 (issue 2984_) +* Fix a bug in register assignment in ARM32 +* Package windows DLLs needed by cffi modules next to the cffi c-extensions + (issue 2988_) +* Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem`` +* Fix memoryviews of ctype structures with padding, (cpython issue 32780_) + +Python 3.6 only + +* On win32, override some ``errno.E*`` values that were added to MSVC in v2010 + so that ``errno.E* == errno.WSAE*`` as in CPython +* Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the + AST level) +* ``str.maketrans`` was broken (issue 2991_) +* Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` + and ``'a' < buffer`` + +.. _2984: https://bitbucket.org/pypy/pypy/issues/2984 +.. _2991: https://bitbucket.org/pypy/pypy/issues/2991 +.. _2988: https://bitbucket.org/pypy/pypy/issues/2988 +.. _32780: https://bugs.python.org/issue32780 From pypy.commits at gmail.com Thu Apr 11 09:18:54 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 11 Apr 2019 06:18:54 -0700 (PDT) Subject: [pypy-commit] cffi default: bump version to 1.12.3 Message-ID: <5caf3ebe.1c69fb81.7e65c.7718@mx.google.com> Author: Armin Rigo Branch: Changeset: r3261:6231d1da1e96 Date: 2019-04-11 15:18 +0200 http://bitbucket.org/cffi/cffi/changeset/6231d1da1e96/ Log: bump version to 1.12.3 diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2,7 +2,7 @@ #include #include "structmember.h" -#define CFFI_VERSION "1.12.2" +#define CFFI_VERSION "1.12.3" #ifdef MS_WIN32 #include diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -14,7 +14,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): diff --git a/cffi/__init__.py b/cffi/__init__.py --- a/cffi/__init__.py +++ b/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.2" -__version_info__ = (1, 12, 2) +__version__ = "1.12.3" +__version_info__ = (1, 12, 3) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -223,7 +223,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.2" + "\ncompiled with cffi version: 1.12.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/doc/source/conf.py b/doc/source/conf.py --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -47,7 +47,7 @@ # The short X.Y version. version = '1.12' # The full version, including alpha/beta/rc tags. -release = '1.12.2' +release = '1.12.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/installation.rst b/doc/source/installation.rst --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -52,13 +52,13 @@ * https://pypi.python.org/pypi/cffi -* Checksums of the "source" package version 1.12.2: +* Checksums of the "source" package version 1.12.3: - - MD5: 4d7dcb6c7c738c15d2ece9bd4c5f86da + - MD5: ... - - SHA: 5f579d4980cbcc8aac592721f714ef6a64370ab1 + - SHA: ... - - SHA256: e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7 + - SHA256: ... * Or grab the most current version from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -198,7 +198,7 @@ `Mailing list `_ """, - version='1.12.2', + version='1.12.3', packages=['cffi'] if cpython else [], package_data={'cffi': ['_cffi_include.h', 'parse_c_type.h', '_embedding.h', '_cffi_errors.h']} From pypy.commits at gmail.com Thu Apr 11 09:21:36 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 11 Apr 2019 06:21:36 -0700 (PDT) Subject: [pypy-commit] pypy default: bump the version of cffi to 1.12.3 Message-ID: <5caf3f60.1c69fb81.df1fa.7a25@mx.google.com> Author: Armin Rigo Branch: Changeset: r96452:aa44105c4d15 Date: 2019-04-11 15:20 +0200 http://bitbucket.org/pypy/pypy/changeset/aa44105c4d15/ Log: bump the version of cffi to 1.12.3 diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.12.2 +Version: 1.12.3 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.2" -__version_info__ = (1, 12, 2) +__version__ = "1.12.3" +__version_info__ = (1, 12, 3) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -223,7 +223,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.2" + "\ncompiled with cffi version: 1.12.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi from rpython.rtyper.lltypesystem import rffi -VERSION = "1.12.2" +VERSION = "1.12.3" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): From pypy.commits at gmail.com Fri Apr 12 04:48:42 2019 From: pypy.commits at gmail.com (stevie_92) Date: Fri, 12 Apr 2019 01:48:42 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Clear weakref callbacks in rawrefcounted garbage to avoid resurrection Message-ID: <5cb050ea.1c69fb81.95787.8e0e@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96453:0b7ae798b964 Date: 2019-04-12 10:47 +0200 http://bitbucket.org/pypy/pypy/changeset/0b7ae798b964/ Log: Clear weakref callbacks in rawrefcounted garbage to avoid resurrection diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py --- a/pypy/module/cpyext/state.py +++ b/pypy/module/cpyext/state.py @@ -160,6 +160,20 @@ pyobj_dealloc_action = PyObjDeallocAction(space) self.dealloc_trigger = lambda: pyobj_dealloc_action.fire() + def _clear_weakref_callbacks(gcref): + from pypy.module._weakref.interp__weakref import \ + W_Weakref, W_CallableProxy + from pypy.module.gc.referents import \ + try_cast_gcref_to_w_root + w_obj = try_cast_gcref_to_w_root(gcref) + if type(w_obj) is W_Weakref: + w_obj.w_callable = None + elif type(w_obj) is W_CallableProxy: + w_obj.w_callable = None + + self.clear_weakref_callbacks = \ + (lambda w_obj: _clear_weakref_callbacks(w_obj)) + def _tp_traverse(pyobj_ptr, callback, args): from pypy.module.cpyext.api import PyObject from pypy.module.cpyext.typeobjectdefs import visitproc @@ -213,7 +227,9 @@ self.tp_traverse), pypyobj_list, self.C._PyPy_gc_as_pyobj, self.C._PyPy_pyobj_as_gc, - self.C._PyPy_finalizer_type) + self.C._PyPy_finalizer_type, + llhelper(rawrefcount.RAWREFCOUNT_CLEAR_WR_TYPE, + self.clear_weakref_callbacks)) self.builder.attach_all(space) setup_new_method_def(space) diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -3112,6 +3112,8 @@ PYOBJ_GC_HDR_PTR)) RAWREFCOUNT_FINALIZER_TYPE = lltype.Ptr(lltype.FuncType([PYOBJ_GC_HDR_PTR], lltype.Signed)) + RAWREFCOUNT_CLEAR_WR_TYPE = lltype.Ptr(lltype.FuncType([llmemory.GCREF], + lltype.Void)) RAWREFCOUNT_FINALIZER_NONE = 0 RAWREFCOUNT_FINALIZER_MODERN = 1 RAWREFCOUNT_FINALIZER_LEGACY = 2 @@ -3124,7 +3126,8 @@ return llmemory.cast_adr_to_ptr(pygchdraddr, self.PYOBJ_GC_HDR_PTR) def rawrefcount_init(self, dealloc_trigger_callback, tp_traverse, - pyobj_list, gc_as_pyobj, pyobj_as_gc, finalizer_type): + pyobj_list, gc_as_pyobj, pyobj_as_gc, finalizer_type, + clear_weakref_callback): # see pypy/doc/discussion/rawrefcount.rst if not self.rrc_enabled: self.rrc_p_list_young = self.AddressStack() @@ -3145,6 +3148,7 @@ self.rrc_gc_as_pyobj = gc_as_pyobj self.rrc_pyobj_as_gc = pyobj_as_gc self.rrc_finalizer_type = finalizer_type + self.rrc_clear_weakref_callback = clear_weakref_callback self.rrc_enabled = True self.rrc_state = self.RAWREFCOUNT_STATE_DEFAULT @@ -3411,10 +3415,6 @@ self.rrc_p_list_old.foreach(self._rrc_major_trace, use_cylicrc) self.rrc_o_list_old.foreach(self._rrc_major_trace, use_cylicrc) - # TODO: handle weakrefs for unreachable objects and create - # TODO: a list of callbacks, which has to be called after the - # TODO: the GC runs - def _rrc_major_trace(self, pyobject, use_cylicrefcnt): from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT @@ -3459,9 +3459,48 @@ if self.rrc_state == self.RAWREFCOUNT_STATE_DEFAULT: if not self._rrc_gc_list_is_empty(self.rrc_pyobj_old_list): + self._rrc_clear_weakref_callbacks() self._rrc_gc_list_merge(self.rrc_pyobj_old_list, self.rrc_pyobj_dead_list) + def _rrc_clear_weakref_callbacks(self): + # Look for any weakrefs within the trash cycle and remove the callback. + # This is only needed for weakrefs created from rawrefcounted objects + # because weakrefs from gc-managed objects are going away anyway. + gchdr = self.rrc_pyobj_old_list.c_gc_next + while gchdr <> self.rrc_pyobj_old_list: + pyobj = self.rrc_gc_as_pyobj(gchdr) + self._rrc_traverse_weakref(pyobj) + gchdr = gchdr.c_gc_next + + def _rrc_visit_weakref(pyobj, self_ptr): + from rpython.rtyper.annlowlevel import cast_adr_to_nongc_instance + # + self_adr = rffi.cast(llmemory.Address, self_ptr) + self = cast_adr_to_nongc_instance(IncrementalMiniMarkGC, self_adr) + self._rrc_visit_weakref_action(pyobj, None) + return rffi.cast(rffi.INT_real, 0) + + def _rrc_visit_weakref_action(self, pyobj, ignore): + intobj = pyobj.c_ob_pypy_link + if intobj <> 0: + obj = llmemory.cast_int_to_adr(intobj) + object = llmemory.cast_adr_to_ptr(obj, llmemory.GCREF) + self.rrc_clear_weakref_callback(object) + + def _rrc_traverse_weakref(self, pyobj): + from rpython.rlib.objectmodel import we_are_translated + from rpython.rtyper.annlowlevel import (cast_nongc_instance_to_adr, + llhelper) + # + if we_are_translated(): + callback_ptr = llhelper(self.RAWREFCOUNT_VISIT, + IncrementalMiniMarkGC._rrc_visit_weakref) + self_ptr = rffi.cast(rffi.VOIDP, cast_nongc_instance_to_adr(self)) + self.rrc_tp_traverse(pyobj, callback_ptr, self_ptr) + else: + self.rrc_tp_traverse(pyobj, self._rrc_visit_weakref_action, None) + def _rrc_major_free(self, pyobject, surviving_list, surviving_dict): # The pyobject survives if the corresponding obj survives. # This is true if the obj has one of the following two flags: @@ -3658,6 +3697,7 @@ self._rrc_gc_list_merge(self.rrc_pyobj_old_list, self.rrc_pyobj_list) else: + self._rrc_clear_weakref_callbacks() self._rrc_gc_list_merge(self.rrc_pyobj_old_list, self.rrc_pyobj_dead_list) diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -486,7 +486,8 @@ SomePtr(GCClass.RAWREFCOUNT_TRAVERSE), SomeAddress(), SomePtr(GCClass.RAWREFCOUNT_GC_AS_PYOBJ), SomePtr(GCClass.RAWREFCOUNT_PYOBJ_AS_GC), - SomePtr(GCClass.RAWREFCOUNT_FINALIZER_TYPE)], + SomePtr(GCClass.RAWREFCOUNT_FINALIZER_TYPE), + SomePtr(GCClass.RAWREFCOUNT_CLEAR_WR_TYPE)], annmodel.s_None) self.rawrefcount_create_link_pypy_ptr = getfn( GCClass.rawrefcount_create_link_pypy, @@ -1365,7 +1366,7 @@ def gct_gc_rawrefcount_init(self, hop): [v_fnptr, v_fnptr2, v_pyobj_list, v_fnptr3, v_fnptr4, - v_fnptr5] = hop.spaceop.args + v_fnptr5, v_fnptr6] = hop.spaceop.args assert v_fnptr.concretetype == self.GCClass.RAWREFCOUNT_DEALLOC_TRIGGER assert v_fnptr2.concretetype == self.GCClass.RAWREFCOUNT_TRAVERSE # TODO add assert for v_pyobj_list, improve asserts (types not same but equal) @@ -1373,7 +1374,8 @@ # assert v_fnptr4.concretetype == self.GCClass.RAWREFCOUNT_PYOBJ_AS_GC hop.genop("direct_call", [self.rawrefcount_init_ptr, self.c_const_gc, v_fnptr, - v_fnptr2, v_pyobj_list, v_fnptr3, v_fnptr4, v_fnptr5]) + v_fnptr2, v_pyobj_list, v_fnptr3, v_fnptr4, v_fnptr5, + v_fnptr6]) def gct_gc_rawrefcount_create_link_pypy(self, hop): [v_gcobj, v_pyobject] = hop.spaceop.args diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py --- a/rpython/rlib/rawrefcount.py +++ b/rpython/rlib/rawrefcount.py @@ -36,6 +36,8 @@ PYOBJ_HDR_PTR)) RAWREFCOUNT_PYOBJ_AS_GC = lltype.Ptr(lltype.FuncType([PYOBJ_HDR_PTR], PYOBJ_GC_HDR_PTR)) +RAWREFCOUNT_CLEAR_WR_TYPE = lltype.Ptr(lltype.FuncType([llmemory.GCREF], + lltype.Void)) def _build_pypy_link(p): @@ -307,21 +309,22 @@ def compute_result_annotation(self, s_dealloc_callback, s_tp_traverse, s_pyobj_list, s_as_gc, s_as_pyobj, - a_finalizer_type): + a_finalizer_type, a_clear_wr): from rpython.rtyper.llannotation import SomePtr assert isinstance(s_dealloc_callback, SomePtr) # ll-ptr-to-function assert isinstance(s_tp_traverse, SomePtr) assert isinstance(s_as_gc, SomePtr) assert isinstance(s_as_pyobj, SomePtr) assert isinstance(a_finalizer_type, SomePtr) + assert isinstance(a_clear_wr, SomePtr) def specialize_call(self, hop): hop.exception_cannot_occur() v_dealloc_callback, v_tp_traverse, v_pyobj_list, v_as_gc, \ - v_as_pyobj, v_finalizer_type = hop.inputargs(*hop.args_r) + v_as_pyobj, v_finalizer_type, v_clear_wr = hop.inputargs(*hop.args_r) hop.genop('gc_rawrefcount_init', [v_dealloc_callback, v_tp_traverse, v_pyobj_list, v_as_gc, v_as_pyobj, - v_finalizer_type]) + v_finalizer_type, v_clear_wr]) class Entry(ExtRegistryEntry): From pypy.commits at gmail.com Sat Apr 13 10:00:48 2019 From: pypy.commits at gmail.com (arigo) Date: Sat, 13 Apr 2019 07:00:48 -0700 (PDT) Subject: [pypy-commit] pypy default: Fix the general testing for newstr(utf8, length_in_number_of_chars), Message-ID: <5cb1eb90.1c69fb81.8c3c3.84ec@mx.google.com> Author: Armin Rigo Branch: Changeset: r96454:1f16a5e43952 Date: 2019-04-13 15:36 +0200 http://bitbucket.org/pypy/pypy/changeset/1f16a5e43952/ Log: Fix the general testing for newstr(utf8, length_in_number_of_chars), which *now* should work and complain if we give an invalid number of chars. Fix array.array for a place where invalid utf8 strings were still being made, found by the above. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -1053,21 +1053,17 @@ code = r_uint(ord(item)) # cpython will allow values > sys.maxunicode # while silently truncating the top bits - if code <= r_uint(0x7F): - # Encode ASCII - item = chr(code) - elif code <= r_uint(0x07FF): - item = (chr((0xc0 | (code >> 6))) + - chr((0x80 | (code & 0x3f)))) - elif code <= r_uint(0xFFFF): - item = (chr((0xe0 | (code >> 12))) + - chr((0x80 | ((code >> 6) & 0x3f))) + - chr((0x80 | (code & 0x3f)))) - else: - item = (chr((0xf0 | (code >> 18)) & 0xff) + - chr((0x80 | ((code >> 12) & 0x3f))) + - chr((0x80 | ((code >> 6) & 0x3f))) + - chr((0x80 | (code & 0x3f)))) + # For now I (arigo) am going to ignore that and + # raise a ValueError always here, instead of getting + # some invalid utf8-encoded string which makes things + # potentially explode left and right. + try: + item = rutf8.unichr_as_utf8(code) + except rutf8.OutOfRange: + raise oefmt(space.w_ValueError, + "cannot operate on this array('u') because it contains" + " character %s not in range [U+0000; U+10ffff]" + " at index %d", 'U+%x' % code, idx) return space.newutf8(item, 1) assert 0, "unreachable" diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -851,7 +851,13 @@ a = self.array('u', input_unicode) b = self.array('u', input_unicode) b.byteswap() - assert a != b + assert b[2] == u'\u0000' + raises(ValueError, "b[1]") # doesn't work + e = raises(ValueError, "a != b") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") assert str(a) == "array('u', %r)" % (input_unicode,) assert str(b) == ("array('u', )") diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -42,13 +42,10 @@ self._length = length self._index_storage = rutf8.null_storage() if not we_are_translated(): - try: - # best effort, too expensive to handle surrogates - ulength = rutf8.codepoints_in_utf(utf8str) - except: - ulength = length - assert ulength == length - + # utf8str must always be a valid utf8 string, except maybe with + # explicit surrogate characters---which .decode('utf-8') doesn't + # special-case in Python 2, which is exactly what we want here + assert length == len(utf8str.decode('utf-8')) @staticmethod From pypy.commits at gmail.com Sat Apr 13 10:13:50 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 13 Apr 2019 07:13:50 -0700 (PDT) Subject: [pypy-commit] pypy winoverlapped: Fixed Subprocess tests Message-ID: <5cb1ee9e.1c69fb81.d7f6b.08e5@mx.google.com> Author: andrewjlawrence Branch: winoverlapped Changeset: r96455:80e8863b95ef Date: 2019-04-13 15:11 +0100 http://bitbucket.org/pypy/pypy/changeset/80e8863b95ef/ Log: Fixed Subprocess tests diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py --- a/lib_pypy/_overlapped.py +++ b/lib_pypy/_overlapped.py @@ -87,6 +87,8 @@ def _int2handle(val): return _ffi.cast("HANDLE", val) +def _int2overlappedptr(val): + return _ffi.cast("OVERLAPPED*", val) def _handle2int(handle): return int(_ffi.cast("intptr_t", handle)) @@ -437,10 +439,10 @@ @property def address(self): - return self.overlapped + return _handle2int(self.overlapped) def SetEvent(handle): - ret = _kernel32.SetEvent(handle) + ret = _kernel32.SetEvent(_int2handle(handle)) if not ret: raise _winapi._WinError() @@ -451,6 +453,7 @@ def CreateEvent(eventattributes, manualreset, initialstate, name): event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name)) + event = _handle2int(event) if not event: raise _winapi._WinError() return event @@ -466,8 +469,7 @@ numberofconcurrentthreads) if result == _ffi.NULL: raise SetFromWindowsErr(0) - - return result + return _handle2int(result) def PostQueuedCompletionStatus(completionport, ms): raise _winapi._WinError() @@ -475,6 +477,7 @@ def GetQueuedCompletionStatus(completionport, milliseconds): numberofbytes = _ffi.new('DWORD[1]', [0]) completionkey = _ffi.new('ULONG**') + completionport = _int2handle(completionport) if completionport is None: raise _winapi._WinError() @@ -495,20 +498,21 @@ return None return SetFromWindowsErr(err) - return (err, numberofbytes, _handle2int(completionkey[0]), _ffi.addressof(overlapped[0][0])) + return (err, numberofbytes, _handle2int(completionkey[0]), _handle2int(_ffi.addressof(overlapped[0][0]))) @_ffi.callback("void(void*, int)") def post_to_queue_callback(lpparameter, timerorwaitfired): - pdata = _ffi.cast("PostCallbackData *", lpparameter) + pdata = _ffi.cast("PostCallbackData*", lpparameter) ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, timerorwaitfired, _ffi.cast("ULONG_PTR",0), pdata.Overlapped) result = False + _winapi.free(pdata) def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds): - data = _ffi.new('PostCallbackData*') + data = _ffi.cast('PostCallbackData*', _winapi.malloc( _ffi.sizeof("PostCallbackData"))) newwaitobject = _ffi.new("HANDLE*") - data[0].hCompletionPort = completionport - data[0].Overlapped = ovaddress + data[0].hCompletionPort = _int2handle(completionport) + data[0].Overlapped = _int2overlappedptr(ovaddress) ret = _kernel32.RegisterWaitForSingleObject(newwaitobject, _int2handle(object), _ffi.cast("WAITORTIMERCALLBACK",post_to_queue_callback), diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -152,6 +152,10 @@ #define WT_EXECUTEINWAITTHREAD 0x00000004 #define WT_EXECUTEONLYONCE 0x00000008 +HANDLE GetProcessHeap(); +LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T); +BOOL HeapFree(HANDLE, DWORD, LPVOID); + """) # -------------------- Win Sock 2 ---------------------- diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py --- a/lib_pypy/_pypy_winbase_cffi.py +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -3,8 +3,8 @@ ffi = _cffi_backend.FFI('_pypy_winbase_cffi', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x5C\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x36\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1B\x03\x00\x01\x2F\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x40\x03\x00\x00\x22\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x22\x11\x00\x01\x3B\x03\x00\x01\x30\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x2E\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x2E\x11\x00\x00\x11\x11\x00\x01\x26\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x1D\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x1D\x11\x00\x00\x1C\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x1D\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1C\x11\x00\x00\x1D\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x3C\x03\x00\x00\x0A\x01\x00\x00\x1C\x11\x00\x00\x1C\x11\x00\x00\x1D\x11\x00\x01\x21\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x59\x11\x00\x00\x0A\x01\x00\x00\x1C\x11\x00\x00\x0A\x01\x00\x00\x1D\x11\x00\x00\x5E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x1C\x11\x00\x00\x1C\x03\x00\x00\x1D\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x1C\x11\x00\x00\x1C\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x1D\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1C\x11\x00\x00\x1D\x11\x00\x00\x5E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x1C\x11\x00\x00\x1D\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x2E\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x5C\x03\x00\x00\x0A\x01\x00\x00\x1C\x11\x00\x00\x1D\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xDD\x03\x00\x00\x07\x01\x00\x01\x3F\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xAE\x11\x00\x00\xAE\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xAE\x11\x00\x00\xAE\x11\x00\x00\x2A\x11\x00\x00\x2B\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x6B\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1B\x0D\x00\x00\x0A\x01\x00\x00\x2E\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1B\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1B\x0D\x00\x00\x11\x11\x00\x00\xAE\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1B\x0D\x00\x00\x02\x0F\x00\x00\xD8\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xD8\x0D\x00\x00\x00\x0F\x00\x00\xD8\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x35\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x40\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xE0\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xDD\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xE3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xE0\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xE3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xE0\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xAE\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xE0\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xE9\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xE0\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x5C\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x5C\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x2C\x03\x00\x00\x13\x09\x00\x01\x2E\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x32\x03\x00\x00\x0E\x09\x00\x01\x34\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x3A\x03\x00\x01\x39\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x3E\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x40\x05\x00\x00\x00\x0E\x00\x01\x40\x05\x00\x00\x00\x08\x00\x00\x48\x03\x00\x00\x4E\x03\x00\x00\x93\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x53\x03\x00\x00\x04\x01\x00\x01\x53\x05\x00\x00\x00\x10\x00\x01\x53\x05\x00\x00\x00\x08\x00\x00\x1B\x05\x00\x00\x00\x07\x00\x00\xD8\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xDD\x05\x00\x00\x01\x00', - _globals = (b'\x00\x00\x3B\x23CancelIo',0,b'\x00\x00\x3E\x23CancelIoEx',0,b'\x00\x00\x3B\x23CloseHandle',0,b'\x00\x00\x3E\x23ConnectNamedPipe',0,b'\x00\x00\xDF\x23CreateEventA',0,b'\x00\x00\xE5\x23CreateEventW',0,b'\x00\x00\xEB\x23CreateFileA',0,b'\x00\x01\x18\x23CreateFileW',0,b'\x00\x01\x06\x23CreateIoCompletionPort',0,b'\x00\x00\xF4\x23CreateNamedPipeA',0,b'\x00\x01\x0E\x23CreateNamedPipeW',0,b'\x00\x00\x2D\x23CreatePipe',0,b'\x00\x00\x21\x23CreateProcessA',0,b'\x00\x00\xB4\x23CreateProcessW',0,b'\x00\x00\x9D\x23DuplicateHandle',0,b'\x00\x01\x0C\x23GetCurrentProcess',0,b'\x00\x00\x6D\x23GetExitCodeProcess',0,b'\x00\x00\xD5\x23GetLastError',0,b'\x00\x00\xD0\x23GetModuleFileNameW',0,b'\x00\x00\x42\x23GetOverlappedResult',0,b'\x00\x00\x71\x23GetQueuedCompletionStatus',0,b'\x00\x01\x03\x23GetStdHandle',0,b'\x00\x00\xD5\x23GetVersion',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\x7E\x23PostQueuedCompletionStatus',0,b'\x00\x00\x18\x23ReadFile',0,b'\x00\x00\x33\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC3\x23SetErrorMode',0,b'\x00\x00\x3B\x23SetEvent',0,b'\x00\x00\x78\x23SetNamedPipeHandleState',0,b'\x00\x00\x69\x23TerminateProcess',0,b'\x00\x00\x3B\x23UnregisterWait',0,b'\x00\x00\x8F\x23UnregisterWaitEx',0,b'\x00\x00\x84\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x57\x23WSARecv',0,b'\x00\x00\x60\x23WSASend',0,b'\x00\x00\xAD\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xC6\x23WaitForMultipleObjects',0,b'\x00\x00\xCC\x23WaitForSingleObject',0,b'\x00\x00\xA6\x23WriteFile',0,b'\x00\x00\xC0\x23_get_osfhandle',0,b'\x00\x00\x1F\x23_getch',0,b'\x00\x00\x1F\x23_getche',0,b'\x00\x00\xDA\x23_getwch',0,b'\x00\x00\xDA\x23_getwche',0,b'\x00\x00\x1F\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xDC\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xD7\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xD7\x23htons',0,b'\x00\x00\xFE\x23socket',0), - _struct_unions = ((b'\x00\x00\x01\x4D\x00\x00\x00\x03$1',b'\x00\x01\x49\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x49\x00\x00\x00\x02$2',b'\x00\x00\x1B\x11Offset',b'\x00\x00\x1B\x11OffsetHigh'),(b'\x00\x00\x01\x4E\x00\x00\x00\x03$3',b'\x00\x01\x54\x11Byte',b'\x00\x01\x5A\x11Word'),(b'\x00\x00\x01\x4F\x00\x00\x00\x01$4',b'\x00\x01\x4A\x11',b'\x00\x00\x1B\x11Value'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02$5',b'\x00\x00\x1B\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1B\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x50\x00\x00\x00\x03$6',b'\x00\x00\x1B\x11sin6_scope_id',b'\x00\x01\x34\x11sin6_scope_struct'),(b'\x00\x00\x01\x51\x00\x00\x00\x03$7',b'\x00\x01\x4B\x11S_un_b',b'\x00\x01\x4C\x11S_un_w',b'\x00\x00\x1B\x11S_addr'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02$8',b'\x00\x01\x53\x11s_b1',b'\x00\x01\x53\x11s_b2',b'\x00\x01\x53\x11s_b3',b'\x00\x01\x53\x11s_b4'),(b'\x00\x00\x01\x4C\x00\x00\x00\x02$9',b'\x00\x00\xD8\x11s_w1',b'\x00\x00\xD8\x11s_w2'),(b'\x00\x00\x01\x30\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1B\x11dwProcessId',b'\x00\x00\x1B\x11dwThreadId'),(b'\x00\x00\x01\x34\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x4F\x11'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1B\x11cb',b'\x00\x00\x22\x11lpReserved',b'\x00\x00\x22\x11lpDesktop',b'\x00\x00\x22\x11lpTitle',b'\x00\x00\x1B\x11dwX',b'\x00\x00\x1B\x11dwY',b'\x00\x00\x1B\x11dwXSize',b'\x00\x00\x1B\x11dwYSize',b'\x00\x00\x1B\x11dwXCountChars',b'\x00\x00\x1B\x11dwYCountChars',b'\x00\x00\x1B\x11dwFillAttribute',b'\x00\x00\x1B\x11dwFlags',b'\x00\x00\xD8\x11wShowWindow',b'\x00\x00\xD8\x11cbReserved2',b'\x00\x01\x52\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x2A\x00\x00\x00\x02_GUID',b'\x00\x00\x1B\x11Data1',b'\x00\x00\xD8\x11Data2',b'\x00\x00\xD8\x11Data3',b'\x00\x01\x56\x11Data4'),(b'\x00\x00\x01\x2F\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1B\x11Internal',b'\x00\x00\x1B\x11InternalHigh',b'\x00\x01\x4D\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x32\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x1D\x11Overlapped'),(b'\x00\x00\x01\x35\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1B\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x3C\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1B\x11len',b'\x00\x00\x22\x11buf'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x58\x11ChainEntries'),(b'\x00\x00\x01\x3F\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1B\x11dwServiceFlags1',b'\x00\x00\x1B\x11dwServiceFlags2',b'\x00\x00\x1B\x11dwServiceFlags3',b'\x00\x00\x1B\x11dwServiceFlags4',b'\x00\x00\x1B\x11dwProviderFlags',b'\x00\x01\x2A\x11ProviderId',b'\x00\x00\x1B\x11dwCatalogEntryId',b'\x00\x01\x3E\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1B\x11dwMessageSize',b'\x00\x00\x1B\x11dwProviderReserved',b'\x00\x01\x5D\x11szProtocol'),(b'\x00\x00\x01\x2C\x00\x00\x00\x02in6_addr',b'\x00\x01\x4E\x11u'),(b'\x00\x00\x01\x2E\x00\x00\x00\x02in_addr',b'\x00\x01\x51\x11S_un'),(b'\x00\x00\x01\x36\x00\x00\x00\x02sockaddr',b'\x00\x00\xD8\x11sa_family',b'\x00\x01\x41\x11sa_data'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x48\x11sin_family',b'\x00\x00\xD8\x11sin_port',b'\x00\x01\x2E\x11sin_addr',b'\x00\x01\x43\x11sin_zero'),(b'\x00\x00\x01\x39\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xD8\x11sin6_family',b'\x00\x00\xD8\x11sin6_port',b'\x00\x00\x1B\x11sin6_flowinfo',b'\x00\x01\x2C\x11sin6_addr',b'\x00\x01\x50\x11')), - _typenames = (b'\x00\x00\x00\xD8ADDRESS_FAMILY',b'\x00\x00\x01\x47AcceptExPtr',b'\x00\x00\x01\x46ConnectExPtr',b'\x00\x00\x01\x45DisconnectExPtr',b'\x00\x00\x01\x2AGUID',b'\x00\x00\x01\x2CIN6_ADDR',b'\x00\x00\x01\x2EINADDR',b'\x00\x00\x01\x45LPFN_DISCONNECTEX',b'\x00\x00\x01\x2BLPIN6_ADDR',b'\x00\x00\x00\x1DLPOVERLAPPED',b'\x00\x00\x00\x5ELPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x2BLPPROCESS_INFORMATION',b'\x00\x00\x01\x31LPPostCallbackData',b'\x00\x00\x00\xE0LPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x37LPSOCKADDR_IN',b'\x00\x00\x01\x38LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2ALPSTARTUPINFO',b'\x00\x00\x00\x59LPWSABUF',b'\x00\x00\x01\x3DLPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB0LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x2FOVERLAPPED',b'\x00\x00\x01\x2BPIN6_ADDR',b'\x00\x00\x01\x2DPINADDR',b'\x00\x00\x01\x30PROCESS_INFORMATION',b'\x00\x00\x01\x33PSCOPE_ID',b'\x00\x00\x00\xE0PSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x37PSOCKADDR_IN',b'\x00\x00\x01\x38PSOCKADDR_IN6_LH',b'\x00\x00\x01\x32PostCallbackData',b'\x00\x00\x01\x34SCOPE_ID',b'\x00\x00\x01\x35SECURITY_ATTRIBUTES',b'\x00\x00\x01\x36SOCKADDR',b'\x00\x00\x01\x3ASOCKADDR_IN',b'\x00\x00\x01\x39SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x3BSTARTUPINFO',b'\x00\x00\x00\x36WAITORTIMERCALLBACK',b'\x00\x00\x01\x3CWSABUF',b'\x00\x00\x01\x3EWSAPROTOCOLCHAIN',b'\x00\x00\x01\x3FWSAPROTOCOL_INFOW',b'\x00\x00\x00\xD8wint_t'), + _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x68\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x42\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x3B\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x4C\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x47\x03\x00\x01\x3C\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x32\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x48\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x2D\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x68\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xE2\x03\x00\x00\x07\x01\x00\x01\x4B\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xDD\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x41\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x4C\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEC\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xE2\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF5\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x68\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x68\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x38\x03\x00\x00\x13\x09\x00\x01\x3A\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x3E\x03\x00\x00\x0E\x09\x00\x01\x40\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x46\x03\x00\x01\x45\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x4A\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x4C\x05\x00\x00\x00\x0E\x00\x01\x4C\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\x98\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x5F\x03\x00\x00\x04\x01\x00\x01\x5F\x05\x00\x00\x00\x10\x00\x01\x5F\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xDD\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xE2\x05\x00\x00\x01\x00', + _globals = (b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xEB\x23CreateEventA',0,b'\x00\x00\xF1\x23CreateEventW',0,b'\x00\x00\xF7\x23CreateFileA',0,b'\x00\x01\x24\x23CreateFileW',0,b'\x00\x01\x12\x23CreateIoCompletionPort',0,b'\x00\x01\x00\x23CreateNamedPipeA',0,b'\x00\x01\x1A\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xB9\x23CreateProcessW',0,b'\x00\x00\xA2\x23DuplicateHandle',0,b'\x00\x01\x18\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xDA\x23GetLastError',0,b'\x00\x00\xD5\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xE9\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x0F\x23GetStdHandle',0,b'\x00\x00\xDA\x23GetVersion',0,b'\x00\x00\xE4\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC8\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xB2\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xCB\x23WaitForMultipleObjects',0,b'\x00\x00\xD1\x23WaitForSingleObject',0,b'\x00\x00\xAB\x23WriteFile',0,b'\x00\x00\xC5\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xDF\x23_getwch',0,b'\x00\x00\xDF\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE1\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xDC\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xDC\x23htons',0,b'\x00\x01\x0A\x23socket',0), + _struct_unions = ((b'\x00\x00\x01\x59\x00\x00\x00\x03$1',b'\x00\x01\x55\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x55\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x5A\x00\x00\x00\x03$3',b'\x00\x01\x60\x11Byte',b'\x00\x01\x66\x11Word'),(b'\x00\x00\x01\x5B\x00\x00\x00\x01$4',b'\x00\x01\x56\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x56\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x5C\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x40\x11sin6_scope_struct'),(b'\x00\x00\x01\x5D\x00\x00\x00\x03$7',b'\x00\x01\x57\x11S_un_b',b'\x00\x01\x58\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x57\x00\x00\x00\x02$8',b'\x00\x01\x5F\x11s_b1',b'\x00\x01\x5F\x11s_b2',b'\x00\x01\x5F\x11s_b3',b'\x00\x01\x5F\x11s_b4'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$9',b'\x00\x00\xDD\x11s_w1',b'\x00\x00\xDD\x11s_w2'),(b'\x00\x00\x01\x3C\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x40\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x5B\x11'),(b'\x00\x00\x01\x47\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xDD\x11wShowWindow',b'\x00\x00\xDD\x11cbReserved2',b'\x00\x01\x5E\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x36\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xDD\x11Data2',b'\x00\x00\xDD\x11Data3',b'\x00\x01\x62\x11Data4'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x59\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x41\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x64\x11ChainEntries'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x36\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x4A\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x69\x11szProtocol'),(b'\x00\x00\x01\x38\x00\x00\x00\x02in6_addr',b'\x00\x01\x5A\x11u'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02in_addr',b'\x00\x01\x5D\x11S_un'),(b'\x00\x00\x01\x42\x00\x00\x00\x02sockaddr',b'\x00\x00\xDD\x11sa_family',b'\x00\x01\x4D\x11sa_data'),(b'\x00\x00\x01\x46\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x54\x11sin_family',b'\x00\x00\xDD\x11sin_port',b'\x00\x01\x3A\x11sin_addr',b'\x00\x01\x4F\x11sin_zero'),(b'\x00\x00\x01\x45\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xDD\x11sin6_family',b'\x00\x00\xDD\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x38\x11sin6_addr',b'\x00\x01\x5C\x11')), + _typenames = (b'\x00\x00\x00\xDDADDRESS_FAMILY',b'\x00\x00\x01\x53AcceptExPtr',b'\x00\x00\x01\x52ConnectExPtr',b'\x00\x00\x01\x51DisconnectExPtr',b'\x00\x00\x01\x36GUID',b'\x00\x00\x01\x38IN6_ADDR',b'\x00\x00\x01\x3AINADDR',b'\x00\x00\x01\x51LPFN_DISCONNECTEX',b'\x00\x00\x01\x37LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x3DLPPostCallbackData',b'\x00\x00\x00\xECLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x43LPSOCKADDR_IN',b'\x00\x00\x01\x44LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x49LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB5LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x3BOVERLAPPED',b'\x00\x00\x01\x37PIN6_ADDR',b'\x00\x00\x01\x39PINADDR',b'\x00\x00\x01\x3CPROCESS_INFORMATION',b'\x00\x00\x01\x3FPSCOPE_ID',b'\x00\x00\x00\xECPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x43PSOCKADDR_IN',b'\x00\x00\x01\x44PSOCKADDR_IN6_LH',b'\x00\x00\x01\x3EPostCallbackData',b'\x00\x00\x01\x40SCOPE_ID',b'\x00\x00\x01\x41SECURITY_ATTRIBUTES',b'\x00\x00\x01\x42SOCKADDR',b'\x00\x00\x01\x46SOCKADDR_IN',b'\x00\x00\x01\x45SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x47STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x48WSABUF',b'\x00\x00\x01\x4AWSAPROTOCOLCHAIN',b'\x00\x00\x01\x4BWSAPROTOCOL_INFOW',b'\x00\x00\x00\xDDwint_t'), ) diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -106,7 +106,7 @@ raise RuntimeError('deleting an overlapped struct with a pending operation not supported') @property - def event(self): + def event(self): xxx return None @@ -288,6 +288,13 @@ raise _WinError() return _ffi.string(buf) +ZERO_MEMORY = 0x00000008 + +def malloc(size): + return _kernel32.HeapAlloc(_kernel32.GetProcessHeap(),ZERO_MEMORY,size) + +def free(voidptr): + _kernel32.HeapFree(_kernel32.GetProcessHeap(),0, voidptr) # #define macros from WinBase.h and elsewhere STD_INPUT_HANDLE = -10 From pypy.commits at gmail.com Sat Apr 13 12:28:49 2019 From: pypy.commits at gmail.com (arigo) Date: Sat, 13 Apr 2019 09:28:49 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Translation fix Message-ID: <5cb20e41.1c69fb81.7eb24.7e66@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96460:c9339f40372b Date: 2019-04-13 18:28 +0200 http://bitbucket.org/pypy/pypy/changeset/c9339f40372b/ Log: Translation fix diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -98,7 +98,9 @@ def listview_ascii(self): if self.is_ascii(): - return list(self._utf8) + return [c for c in self._utf8] + # rpython note: can't use list() to return a list of strings + # (only a list of chars is supported) return None def descr_iter(self, space): From pypy.commits at gmail.com Sat Apr 13 15:20:03 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 13 Apr 2019 12:20:03 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: Pull use_unrolling() call out of optimize_trace() Message-ID: <5cb23663.1c69fb81.63afa.9d8e@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96463:dab1526f28a6 Date: 2019-04-13 20:19 +0100 http://bitbucket.org/pypy/pypy/changeset/dab1526f28a6/ Log: Pull use_unrolling() call out of optimize_trace() diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -8,8 +8,6 @@ from rpython.rlib import rstack from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside from rpython.rlib.rjitlog import rjitlog as jl -from rpython.rlib.objectmodel import compute_unique_id -from rpython.conftest import option from rpython.jit.metainterp.resoperation import ResOperation, rop,\ get_deep_immutable_oplist, OpHelpers, InputArgInt, InputArgRef,\ @@ -138,6 +136,7 @@ self.call_pure_results, self.inline_short_preamble) def show_procedures(metainterp_sd, procedure=None, error=None): + from rpython.conftest import option # debugging if option and (option.view or option.viewloops): if error: @@ -218,7 +217,7 @@ def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts, cut_at): - from rpython.jit.metainterp.optimizeopt import optimize_trace + from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling jitdriver_sd = metainterp.jitdriver_sd metainterp_sd = metainterp.staticdata @@ -226,9 +225,11 @@ call_pure_results = metainterp.call_pure_results data = SimpleCompileData(trace, call_pure_results=call_pure_results, enable_opts=enable_opts) + use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: - loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd, - data, metainterp.box_names_memo) + loop_info, ops = optimize_trace( + metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo, + use_unrolling=use_unroll) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() trace.cut_at(cut_at) @@ -257,7 +258,7 @@ """Try to compile a new procedure by closing the current history back to the first operation. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace + from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd @@ -269,18 +270,20 @@ faildescr=None, entry_bridge=False) # enable_opts = jitdriver_sd.warmstate.enable_opts + use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) if try_disabling_unroll: - if 'unroll' not in enable_opts: + if not use_unroll: return None enable_opts = enable_opts.copy() del enable_opts['unroll'] + use_unroll = False jitcell_token = make_jitcell_token(jitdriver_sd) cut_at = history.get_trace_position() history.record(rop.JUMP, jumpargs, None, descr=jitcell_token) if start != (0, 0, 0): trace = trace.cut_trace_from(start, inputargs) - if 'unroll' not in enable_opts or not metainterp.cpu.supports_guard_gc_type: + if not use_unroll: return compile_simple_loop(metainterp, greenkey, trace, jumpargs, enable_opts, cut_at) call_pure_results = metainterp.call_pure_results @@ -288,9 +291,9 @@ call_pure_results=call_pure_results, enable_opts=enable_opts) try: - start_state, preamble_ops = optimize_trace(metainterp_sd, jitdriver_sd, - preamble_data, - metainterp.box_names_memo) + start_state, preamble_ops = optimize_trace( + metainterp_sd, jitdriver_sd, preamble_data, + metainterp.box_names_memo, use_unrolling=use_unroll) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut_at) @@ -305,9 +308,9 @@ call_pure_results=call_pure_results, enable_opts=enable_opts) try: - loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, - loop_data, - metainterp.box_names_memo) + loop_info, loop_ops = optimize_trace( + metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo, + use_unrolling=use_unroll) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut_at) @@ -354,7 +357,7 @@ """Try to compile a new procedure by closing the current history back to the first operation. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace + from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling trace = metainterp.history.trace.cut_trace_from(start, inputargs) metainterp_sd = metainterp.staticdata @@ -374,10 +377,11 @@ loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state, call_pure_results=call_pure_results, enable_opts=enable_opts) + use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: - loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, - loop_data, - metainterp.box_names_memo) + loop_info, loop_ops = optimize_trace( + metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo, + use_unrolling=use_unroll) except InvalidLoop: # Fall back on jumping directly to preamble history.cut(cut) @@ -387,9 +391,9 @@ enable_opts=enable_opts, inline_short_preamble=False) try: - loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, - loop_data, - metainterp.box_names_memo) + loop_info, loop_ops = optimize_trace( + metainterp_sd, jitdriver_sd, loop_data, + metainterp.box_names_memo, use_unrolling=use_unroll) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut) @@ -1048,7 +1052,7 @@ to some existing place. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace + from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. @@ -1084,13 +1088,13 @@ data = SimpleCompileData(trace, resumestorage, call_pure_results=call_pure_results, enable_opts=enable_opts) + use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: - info, newops = optimize_trace(metainterp_sd, jitdriver_sd, - data, metainterp.box_names_memo) + info, newops = optimize_trace( + metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo, + use_unrolling=use_unroll) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() - #pdb.post_mortem(sys.exc_info()[2]) - debug_print("compile_new_bridge: got an InvalidLoop") # XXX I am fairly convinced that optimize_bridge cannot actually raise # InvalidLoop debug_print('InvalidLoop in compile_new_bridge') diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -53,7 +53,8 @@ if not is_unrolled: metainterp_sd.logger_noopt.log_loop_from_trace(trace, memo=memo) -def optimize_trace(metainterp_sd, jitdriver_sd, compile_data, memo=None): +def optimize_trace(metainterp_sd, jitdriver_sd, compile_data, + memo=None, use_unrolling=True): """Optimize loop.operations to remove internal overheadish operations. """ debug_start("jit-optimize") @@ -63,10 +64,9 @@ if memo is None: memo = {} compile_data.box_names_memo = memo - unroll = use_unrolling(metainterp_sd.cpu, compile_data.enable_opts) optimizations = build_opt_chain(compile_data.enable_opts) return compile_data.optimize(metainterp_sd, jitdriver_sd, - optimizations, unroll) + optimizations, unroll=use_unrolling) finally: compile_data.forget_optimization_info() debug_stop("jit-optimize") diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -5,6 +5,7 @@ from rpython.rlib.rarithmetic import LONG_BIT from rpython.rtyper import rclass from rpython.rtyper.lltypesystem import lltype +from rpython.jit.metainterp.optimizeopt import use_unrolling from rpython.jit.metainterp.optimizeopt.test.test_util import ( BaseTest, FakeMetaInterpStaticData, convert_old_style_to_targets) from rpython.jit.metainterp.history import ( @@ -33,13 +34,13 @@ expected = convert_old_style_to_targets(exp, jump=True) call_pure_results = self._convert_call_pure_results(call_pure_results) trace = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) + use_unroll = use_unrolling(self.cpu, self.enable_opts) compile_data = compile.SimpleCompileData( trace, call_pure_results=call_pure_results) - info, ops = self._do_optimize_loop(compile_data) + info, ops = self._do_optimize_loop(compile_data, use_unroll) label_op = ResOperation(rop.LABEL, info.inputargs) loop.inputargs = info.inputargs loop.operations = [label_op] + ops - #print '\n'.join([str(o) for o in loop.operations]) self.loop = loop self.assert_equal(loop, expected) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py @@ -1,3 +1,4 @@ +from rpython.jit.metainterp.optimizeopt import use_unrolling from rpython.jit.metainterp.optimizeopt.test.test_util import ( BaseTest, convert_old_style_to_targets, FakeMetaInterpStaticData) from rpython.jit.metainterp import compile @@ -29,12 +30,13 @@ self.add_guard_future_condition(bridge) trace = oparser.convert_loop_to_trace( bridge, FakeMetaInterpStaticData(self.cpu)) + use_unroll = use_unrolling(self.cpu, self.enable_opts) data = compile.BridgeCompileData( trace, self.convert_values(bridge.operations[-1].getarglist(), bridge_values), None, enable_opts=self.enable_opts, inline_short_preamble=inline_short_preamble) - bridge_info, ops = self._do_optimize_loop(data) + bridge_info, ops = self._do_optimize_loop(data, use_unroll) loop.check_consistency(check_descr=False) info.preamble.check_consistency(check_descr=False) bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] + diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py --- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py @@ -5,7 +5,7 @@ from rpython.jit.metainterp.optimizeopt.test.test_util import ( BaseTest, FakeMetaInterpStaticData) from rpython.jit.metainterp.optimizeopt.util import equaloplists -from rpython.jit.metainterp.history import TreeLoop, JitCellToken +from rpython.jit.metainterp.history import TreeLoop from rpython.jit.metainterp.resoperation import ( rop, ResOperation, InputArgRef, InputArgInt) from rpython.jit.metainterp.support import ptr2int @@ -16,6 +16,7 @@ NotVirtualStateInfo, LEVEL_CONSTANT, LEVEL_UNKNOWN, LEVEL_KNOWNCLASS, VirtualStateInfo) from rpython.jit.metainterp.optimizeopt import info, optimizer +from rpython.jit.metainterp.optimizeopt import use_unrolling from rpython.jit.tool import oparser class FakeOptimizer(object): @@ -40,20 +41,15 @@ def optimize(self, ops): loop = self.parse(ops) self.add_guard_future_condition(loop) - operations = loop.operations + operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs - - jump_args = jumpop.getarglist()[:] - operations = operations[:-1] - preamble = TreeLoop('preamble') - - token = JitCellToken() trace = oparser.convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) + use_unroll = use_unrolling(self.cpu, self.enable_opts) compile_data = LoopCompileData(trace, inputargs) - start_state, newops = self._do_optimize_loop(compile_data) + start_state, newops = self._do_optimize_loop(compile_data, use_unroll) preamble.operations = newops preamble.inputargs = start_state.renamed_inputargs return start_state, loop, preamble diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py --- a/rpython/jit/metainterp/optimizeopt/test/test_util.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py @@ -23,7 +23,7 @@ from rpython.jit.metainterp.resoperation import ( rop, ResOperation, InputArgRef, AbstractValue) from rpython.jit.metainterp.virtualref import VirtualRefInfo -from rpython.jit.metainterp.optimizeopt import optimize_trace +from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling from rpython.jit.metainterp.optimizeopt.util import ( sort_descrs, equaloplists, args_dict) @@ -538,17 +538,17 @@ assert equaloplists(optimized.operations, expected.operations, False, remap, text_right) - def _do_optimize_loop(self, compile_data): + def _do_optimize_loop(self, compile_data, use_unroll): metainterp_sd = FakeMetaInterpStaticData(self.cpu) metainterp_sd.virtualref_info = self.vrefinfo compute_bitstrings(self.cpu.fetch_all_descrs()) # compile_data.enable_opts = self.enable_opts - state = optimize_trace(metainterp_sd, None, compile_data) + state = optimize_trace( + metainterp_sd, None, compile_data, use_unrolling=use_unroll) return state def _convert_call_pure_results(self, d): - if d is None: return call_pure_results = args_dict() @@ -581,18 +581,16 @@ celltoken = JitCellToken() runtime_boxes = self.pack_into_boxes(jump_op, jump_values) jump_op.setdescr(celltoken) - #start_label = ResOperation(rop.LABEL, loop.inputargs, - # descr=jump_op.getdescr()) - #end_label = jump_op.copy_and_change(opnum=rop.LABEL) call_pure_results = self._convert_call_pure_results(call_pure_results) t = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) + use_unroll = use_unrolling(self.cpu, self.enable_opts) preamble_data = compile.LoopCompileData(t, runtime_boxes, call_pure_results) - start_state, preamble_ops = self._do_optimize_loop(preamble_data) + start_state, preamble_ops = self._do_optimize_loop(preamble_data, use_unroll) preamble_data.forget_optimization_info() loop_data = compile.UnrolledLoopData(preamble_data.trace, celltoken, start_state, call_pure_results) - loop_info, ops = self._do_optimize_loop(loop_data) + loop_info, ops = self._do_optimize_loop(loop_data, use_unroll) preamble = TreeLoop('preamble') preamble.inputargs = start_state.renamed_inputargs start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py @@ -853,7 +853,7 @@ enable_opts = "intbounds:rewrite:virtualize:string:pure:earlyforce:heap:unroll" def _do_optimize_bridge(self, bridge, call_pure_results, values): - from rpython.jit.metainterp.optimizeopt import optimize_trace + from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling from rpython.jit.metainterp.optimizeopt.util import args_dict self.bridge = bridge @@ -871,7 +871,9 @@ data = compile.BridgeCompileData(trace, runtime_boxes, enable_opts=self.enable_opts, inline_short_preamble=True) - info, newops = optimize_trace(metainterp_sd, None, data) + use_unroll = use_unrolling(self.cpu, self.enable_opts) + info, newops = optimize_trace(metainterp_sd, None, data, + use_unrolling=use_unroll) if info.final(): bridge.operations = newops bridge.inputargs = info.inputargs diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -2901,6 +2901,8 @@ optimizeopt.optimize_trace = old_optimize_trace def test_max_unroll_loops_retry_without_unroll(self): + if not self.basic: + py.test.skip("unrolling") from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp import optimizeopt myjitdriver = JitDriver(greens = [], reds = ['n', 'i']) @@ -2916,14 +2918,14 @@ return i # seen = [] - def my_optimize_trace(metainterp_sd, jitdriver_sd, data, memo=None): - seen.append('unroll' in data.enable_opts) + def my_optimize_trace(metainterp_sd, jitdriver_sd, data, memo=None, + use_unrolling=True): + assert use_unrolling == ('unroll' in data.enable_opts) + seen.append(use_unrolling) raise InvalidLoop old_optimize_trace = optimizeopt.optimize_trace optimizeopt.optimize_trace = my_optimize_trace try: - if not self.basic: - py.test.skip("unrolling") res = self.meta_interp(f, [23, 4]) assert res == 23 assert False in seen From pypy.commits at gmail.com Sat Apr 13 15:54:42 2019 From: pypy.commits at gmail.com (mattip) Date: Sat, 13 Apr 2019 12:54:42 -0700 (PDT) Subject: [pypy-commit] pypy issue2996: add a failing test (issue 2996) Message-ID: <5cb23e82.1c69fb81.9d565.19ca@mx.google.com> Author: Matti Picus Branch: issue2996 Changeset: r96464:f91f6fa3ca10 Date: 2019-04-13 22:51 +0300 http://bitbucket.org/pypy/pypy/changeset/f91f6fa3ca10/ Log: add a failing test (issue 2996) diff --git a/pypy/objspace/std/test/test_callmethod.py b/pypy/objspace/std/test/test_callmethod.py --- a/pypy/objspace/std/test/test_callmethod.py +++ b/pypy/objspace/std/test/test_callmethod.py @@ -22,6 +22,17 @@ assert c.m(**{'u': 4}) == ((c,), {'u': 4}) """) + def test_call_star(self): + exec("""if 1: + class Foo: + def meth(self, a1, *args, offset=42): + return args, offset + + ret = Foo().meth(12, **{}) + assert type(ret[0][0]) is Foo + assert ret[1] == 42 + """) + def test_call_attribute(self): exec("""if 1: class C(object): From pypy.commits at gmail.com Sat Apr 13 19:18:37 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 13 Apr 2019 16:18:37 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: LoopCompileData.optimize() is only called with unroll=True; simplify optimize() and optimize_trace() Message-ID: <5cb26e4d.1c69fb81.e93a8.dc6e@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96465:f6577bae1fb3 Date: 2019-04-13 23:52 +0100 http://bitbucket.org/pypy/pypy/changeset/f6577bae1fb3/ Log: LoopCompileData.optimize() is only called with unroll=True; simplify optimize() and optimize_trace() diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -35,7 +35,7 @@ for arg in self.trace.inputargs: arg.set_forwarded(None) -class LoopCompileData(CompileData): +class PreambleCompileData(CompileData): """ An object that accumulates all of the necessary info for the optimization phase, but does not actually have any other state @@ -49,19 +49,13 @@ assert runtime_boxes is not None self.runtime_boxes = runtime_boxes - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): - from rpython.jit.metainterp.optimizeopt.unroll import (UnrollOptimizer, - Optimizer) - - if unroll: - opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) - return opt.optimize_preamble(self.trace, - self.runtime_boxes, - self.call_pure_results, - self.box_names_memo) - else: - opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations) - return opt.propagate_all_forward(self.trace, self.call_pure_results) + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): + from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer + opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) + return opt.optimize_preamble(self.trace, + self.runtime_boxes, + self.call_pure_results, + self.box_names_memo) class SimpleCompileData(CompileData): """ This represents label() ops jump with no extra info associated with @@ -74,11 +68,9 @@ self.call_pure_results = call_pure_results self.enable_opts = enable_opts - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer from rpython.jit.metainterp.optimizeopt.bridgeopt import deserialize_optimizer_knowledge - - #assert not unroll opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations) traceiter = self.trace.get_iter() if self.resumestorage: @@ -101,7 +93,7 @@ self.inline_short_preamble = inline_short_preamble self.resumestorage = resumestorage - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) @@ -113,7 +105,7 @@ class UnrolledLoopData(CompileData): """ This represents label() ops jump with extra info that's from the - run of LoopCompileData. Jump goes to the same label + run of PreambleCompileData. Jump goes to the same label """ log_noopt = False @@ -127,10 +119,8 @@ self.call_pure_results = call_pure_results self.inline_short_preamble = inline_short_preamble - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer - - assert unroll # we should not be here if it's disabled opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) return opt.optimize_peeled_loop(self.trace, self.celltoken, self.state, self.call_pure_results, self.inline_short_preamble) @@ -217,7 +207,7 @@ def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts, cut_at): - from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling + from rpython.jit.metainterp.optimizeopt import optimize_trace jitdriver_sd = metainterp.jitdriver_sd metainterp_sd = metainterp.staticdata @@ -225,11 +215,9 @@ call_pure_results = metainterp.call_pure_results data = SimpleCompileData(trace, call_pure_results=call_pure_results, enable_opts=enable_opts) - use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: loop_info, ops = optimize_trace( - metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo, - use_unrolling=use_unroll) + metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() trace.cut_at(cut_at) @@ -287,13 +275,13 @@ return compile_simple_loop(metainterp, greenkey, trace, jumpargs, enable_opts, cut_at) call_pure_results = metainterp.call_pure_results - preamble_data = LoopCompileData(trace, jumpargs, + preamble_data = PreambleCompileData(trace, jumpargs, call_pure_results=call_pure_results, enable_opts=enable_opts) try: start_state, preamble_ops = optimize_trace( metainterp_sd, jitdriver_sd, preamble_data, - metainterp.box_names_memo, use_unrolling=use_unroll) + metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut_at) @@ -309,8 +297,7 @@ enable_opts=enable_opts) try: loop_info, loop_ops = optimize_trace( - metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo, - use_unrolling=use_unroll) + metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut_at) @@ -373,15 +360,15 @@ cut = history.get_trace_position() history.record(rop.JUMP, jumpargs[:], None, descr=loop_jitcell_token) enable_opts = jitdriver_sd.warmstate.enable_opts + use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) + assert use_unroll call_pure_results = metainterp.call_pure_results loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state, call_pure_results=call_pure_results, enable_opts=enable_opts) - use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: loop_info, loop_ops = optimize_trace( - metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo, - use_unrolling=use_unroll) + metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo) except InvalidLoop: # Fall back on jumping directly to preamble history.cut(cut) @@ -393,7 +380,7 @@ try: loop_info, loop_ops = optimize_trace( metainterp_sd, jitdriver_sd, loop_data, - metainterp.box_names_memo, use_unrolling=use_unroll) + metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut) @@ -1091,8 +1078,7 @@ use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: info, newops = optimize_trace( - metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo, - use_unrolling=use_unroll) + metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() # XXX I am fairly convinced that optimize_bridge cannot actually raise diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -53,8 +53,7 @@ if not is_unrolled: metainterp_sd.logger_noopt.log_loop_from_trace(trace, memo=memo) -def optimize_trace(metainterp_sd, jitdriver_sd, compile_data, - memo=None, use_unrolling=True): +def optimize_trace(metainterp_sd, jitdriver_sd, compile_data, memo=None): """Optimize loop.operations to remove internal overheadish operations. """ debug_start("jit-optimize") @@ -65,8 +64,8 @@ memo = {} compile_data.box_names_memo = memo optimizations = build_opt_chain(compile_data.enable_opts) - return compile_data.optimize(metainterp_sd, jitdriver_sd, - optimizations, unroll=use_unrolling) + return compile_data.optimize( + metainterp_sd, jitdriver_sd, optimizations) finally: compile_data.forget_optimization_info() debug_stop("jit-optimize") diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -5,7 +5,6 @@ from rpython.rlib.rarithmetic import LONG_BIT from rpython.rtyper import rclass from rpython.rtyper.lltypesystem import lltype -from rpython.jit.metainterp.optimizeopt import use_unrolling from rpython.jit.metainterp.optimizeopt.test.test_util import ( BaseTest, FakeMetaInterpStaticData, convert_old_style_to_targets) from rpython.jit.metainterp.history import ( @@ -34,10 +33,9 @@ expected = convert_old_style_to_targets(exp, jump=True) call_pure_results = self._convert_call_pure_results(call_pure_results) trace = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) - use_unroll = use_unrolling(self.cpu, self.enable_opts) compile_data = compile.SimpleCompileData( trace, call_pure_results=call_pure_results) - info, ops = self._do_optimize_loop(compile_data, use_unroll) + info, ops = self._do_optimize_loop(compile_data) label_op = ResOperation(rop.LABEL, info.inputargs) loop.inputargs = info.inputargs loop.operations = [label_op] + ops diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebridge.py @@ -1,4 +1,3 @@ -from rpython.jit.metainterp.optimizeopt import use_unrolling from rpython.jit.metainterp.optimizeopt.test.test_util import ( BaseTest, convert_old_style_to_targets, FakeMetaInterpStaticData) from rpython.jit.metainterp import compile @@ -30,13 +29,12 @@ self.add_guard_future_condition(bridge) trace = oparser.convert_loop_to_trace( bridge, FakeMetaInterpStaticData(self.cpu)) - use_unroll = use_unrolling(self.cpu, self.enable_opts) data = compile.BridgeCompileData( trace, self.convert_values(bridge.operations[-1].getarglist(), bridge_values), None, enable_opts=self.enable_opts, inline_short_preamble=inline_short_preamble) - bridge_info, ops = self._do_optimize_loop(data, use_unroll) + bridge_info, ops = self._do_optimize_loop(data) loop.check_consistency(check_descr=False) info.preamble.check_consistency(check_descr=False) bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] + diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py --- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py @@ -11,12 +11,11 @@ from rpython.jit.metainterp.support import ptr2int from rpython.jit.metainterp.optimizeopt.shortpreamble import ( ShortPreambleBuilder, PreambleOp, ShortInputArg) -from rpython.jit.metainterp.compile import LoopCompileData +from rpython.jit.metainterp.compile import PreambleCompileData from rpython.jit.metainterp.optimizeopt.virtualstate import ( NotVirtualStateInfo, LEVEL_CONSTANT, LEVEL_UNKNOWN, LEVEL_KNOWNCLASS, VirtualStateInfo) from rpython.jit.metainterp.optimizeopt import info, optimizer -from rpython.jit.metainterp.optimizeopt import use_unrolling from rpython.jit.tool import oparser class FakeOptimizer(object): @@ -47,9 +46,8 @@ inputargs = loop.inputargs preamble = TreeLoop('preamble') trace = oparser.convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) - use_unroll = use_unrolling(self.cpu, self.enable_opts) - compile_data = LoopCompileData(trace, inputargs) - start_state, newops = self._do_optimize_loop(compile_data, use_unroll) + compile_data = PreambleCompileData(trace, inputargs) + start_state, newops = self._do_optimize_loop(compile_data) preamble.operations = newops preamble.inputargs = start_state.renamed_inputargs return start_state, loop, preamble diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py --- a/rpython/jit/metainterp/optimizeopt/test/test_util.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py @@ -23,7 +23,7 @@ from rpython.jit.metainterp.resoperation import ( rop, ResOperation, InputArgRef, AbstractValue) from rpython.jit.metainterp.virtualref import VirtualRefInfo -from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling +from rpython.jit.metainterp.optimizeopt import optimize_trace from rpython.jit.metainterp.optimizeopt.util import ( sort_descrs, equaloplists, args_dict) @@ -538,14 +538,13 @@ assert equaloplists(optimized.operations, expected.operations, False, remap, text_right) - def _do_optimize_loop(self, compile_data, use_unroll): + def _do_optimize_loop(self, compile_data): metainterp_sd = FakeMetaInterpStaticData(self.cpu) metainterp_sd.virtualref_info = self.vrefinfo compute_bitstrings(self.cpu.fetch_all_descrs()) # compile_data.enable_opts = self.enable_opts - state = optimize_trace( - metainterp_sd, None, compile_data, use_unrolling=use_unroll) + state = optimize_trace(metainterp_sd, None, compile_data) return state def _convert_call_pure_results(self, d): @@ -583,14 +582,13 @@ jump_op.setdescr(celltoken) call_pure_results = self._convert_call_pure_results(call_pure_results) t = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) - use_unroll = use_unrolling(self.cpu, self.enable_opts) - preamble_data = compile.LoopCompileData(t, runtime_boxes, - call_pure_results) - start_state, preamble_ops = self._do_optimize_loop(preamble_data, use_unroll) + preamble_data = compile.PreambleCompileData( + t, runtime_boxes, call_pure_results, enable_opts=self.enable_opts) + start_state, preamble_ops = self._do_optimize_loop(preamble_data) preamble_data.forget_optimization_info() loop_data = compile.UnrolledLoopData(preamble_data.trace, celltoken, start_state, call_pure_results) - loop_info, ops = self._do_optimize_loop(loop_data, use_unroll) + loop_info, ops = self._do_optimize_loop(loop_data) preamble = TreeLoop('preamble') preamble.inputargs = start_state.renamed_inputargs start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py @@ -853,7 +853,7 @@ enable_opts = "intbounds:rewrite:virtualize:string:pure:earlyforce:heap:unroll" def _do_optimize_bridge(self, bridge, call_pure_results, values): - from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling + from rpython.jit.metainterp.optimizeopt import optimize_trace from rpython.jit.metainterp.optimizeopt.util import args_dict self.bridge = bridge @@ -871,9 +871,7 @@ data = compile.BridgeCompileData(trace, runtime_boxes, enable_opts=self.enable_opts, inline_short_preamble=True) - use_unroll = use_unrolling(self.cpu, self.enable_opts) - info, newops = optimize_trace(metainterp_sd, None, data, - use_unrolling=use_unroll) + info, newops = optimize_trace(metainterp_sd, None, data) if info.final(): bridge.operations = newops bridge.inputargs = info.inputargs diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -2918,9 +2918,8 @@ return i # seen = [] - def my_optimize_trace(metainterp_sd, jitdriver_sd, data, memo=None, - use_unrolling=True): - assert use_unrolling == ('unroll' in data.enable_opts) + def my_optimize_trace(metainterp_sd, jitdriver_sd, data, memo=None): + use_unrolling = ('unroll' in data.enable_opts) seen.append(use_unrolling) raise InvalidLoop old_optimize_trace = optimizeopt.optimize_trace From pypy.commits at gmail.com Sat Apr 13 19:37:09 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 13 Apr 2019 16:37:09 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: remove broken test Message-ID: <5cb272a5.1c69fb81.c9c8.6d53@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96466:eebbb92a8dfb Date: 2019-04-14 00:36 +0100 http://bitbucket.org/pypy/pypy/changeset/eebbb92a8dfb/ Log: remove broken test diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -4072,64 +4072,6 @@ class TestLLtype(BaseLLtypeTests, LLJitMixin): - def test_tagged(self): - py.test.skip("tagged unsupported") - from rpython.rlib.objectmodel import UnboxedValue - class Base(object): - __slots__ = () - - class Int(UnboxedValue, Base): - __slots__ = ["a"] - - def is_pos(self): - return self.a > 0 - - def dec(self): - try: - return Int(self.a - 1) - except OverflowError: - raise - - class Float(Base): - def __init__(self, a): - self.a = a - - def is_pos(self): - return self.a > 0 - - def dec(self): - return Float(self.a - 1) - - driver = JitDriver(greens=['pc', 's'], reds=['o']) - - def main(fl, n, s): - if s: - s = "--j" - else: - s = "---j" - if fl: - o = Float(float(n)) - else: - o = Int(n) - pc = 0 - while True: - driver.jit_merge_point(s=s, pc=pc, o=o) - c = s[pc] - if c == "j": - driver.can_enter_jit(s=s, pc=pc, o=o) - if o.is_pos(): - pc = 0 - continue - else: - break - elif c == "-": - o = o.dec() - pc += 1 - return pc - topt = {'taggedpointers': True} - res = self.meta_interp(main, [False, 100, True], - translationoptions=topt) - def test_rerased(self): eraseX, uneraseX = rerased.new_erasing_pair("X") # From pypy.commits at gmail.com Sun Apr 14 02:21:57 2019 From: pypy.commits at gmail.com (mattip) Date: Sat, 13 Apr 2019 23:21:57 -0700 (PDT) Subject: [pypy-commit] pypy default: mention cffi 1.12.3 in the release note Message-ID: <5cb2d185.1c69fb81.14dda.56a1@mx.google.com> Author: Matti Picus Branch: Changeset: r96467:e36da833300d Date: 2019-04-12 16:13 +0300 http://bitbucket.org/pypy/pypy/changeset/e36da833300d/ Log: mention cffi 1.12.3 in the release note diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -79,6 +79,7 @@ (issue 2988_) * Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem`` * Fix memoryviews of ctype structures with padding, (cpython issue 32780_) +* CFFI updated to as-yet-unreleased 1.12.3 Python 3.6 only From pypy.commits at gmail.com Sun Apr 14 02:21:59 2019 From: pypy.commits at gmail.com (mattip) Date: Sat, 13 Apr 2019 23:21:59 -0700 (PDT) Subject: [pypy-commit] pypy issue2996: fix varargname in Signature Message-ID: <5cb2d187.1c69fb81.80d2a.8bd2@mx.google.com> Author: Matti Picus Branch: issue2996 Changeset: r96468:7e0bd0b3f7d1 Date: 2019-04-14 09:19 +0300 http://bitbucket.org/pypy/pypy/changeset/7e0bd0b3f7d1/ Log: fix varargname in Signature diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -63,7 +63,7 @@ else: kwonlyargs = None if code.co_flags & CO_VARARGS: - varargname = varnames[argcount] + varargname = varnames[argcount + kwonlyargcount] argcount += 1 else: varargname = None From pypy.commits at gmail.com Sun Apr 14 02:22:00 2019 From: pypy.commits at gmail.com (mattip) Date: Sat, 13 Apr 2019 23:22:00 -0700 (PDT) Subject: [pypy-commit] pypy issue2996: add test_call_starstar2 which passes Message-ID: <5cb2d188.1c69fb81.95787.f7fb@mx.google.com> Author: Matti Picus Branch: issue2996 Changeset: r96469:1c0ce86bca73 Date: 2019-04-14 09:20 +0300 http://bitbucket.org/pypy/pypy/changeset/1c0ce86bca73/ Log: add test_call_starstar2 which passes diff --git a/pypy/objspace/std/test/test_callmethod.py b/pypy/objspace/std/test/test_callmethod.py --- a/pypy/objspace/std/test/test_callmethod.py +++ b/pypy/objspace/std/test/test_callmethod.py @@ -22,15 +22,25 @@ assert c.m(**{'u': 4}) == ((c,), {'u': 4}) """) - def test_call_star(self): + def test_call_starstar1(self): exec("""if 1: class Foo: - def meth(self, a1, *args, offset=42): - return args, offset + def meth(*args, a=2): + return args, a + ret = Foo().meth(**{}) + assert type(ret[0][0]) is Foo + assert ret[1] == 2 + """) - ret = Foo().meth(12, **{}) + def test_call_starstar2(self): + exec("""if 1: + class Foo: + def meth(*args, a=2, b=3): + return args, a, b + ret = Foo().meth(**{}) assert type(ret[0][0]) is Foo - assert ret[1] == 42 + assert ret[1] == 2 + assert ret[2] == 3 """) def test_call_attribute(self): From pypy.commits at gmail.com Sun Apr 14 02:26:51 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 13 Apr 2019 23:26:51 -0700 (PDT) Subject: [pypy-commit] pypy winoverlapped: Update whatsnew. Message-ID: <5cb2d2ab.1c69fb81.aa5cb.91bb@mx.google.com> Author: andrewjlawrence Branch: winoverlapped Changeset: r96470:b2a3694d9807 Date: 2019-04-14 07:23 +0100 http://bitbucket.org/pypy/pypy/changeset/b2a3694d9807/ Log: Update whatsnew. diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -8,3 +8,8 @@ .. branch: zlib-make-py3-go-boom Complain if you try to copy a flushed zlib decompress on py3 + +.. branch: winoverlapped + +Add support for async (overlapped) IO on Windows. + From pypy.commits at gmail.com Sun Apr 14 02:37:59 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 13 Apr 2019 23:37:59 -0700 (PDT) Subject: [pypy-commit] pypy winoverlapped: close branch to be merged Message-ID: <5cb2d547.1c69fb81.82e8f.38bb@mx.google.com> Author: andrewjlawrence Branch: winoverlapped Changeset: r96471:355b75ea7623 Date: 2019-04-14 07:29 +0100 http://bitbucket.org/pypy/pypy/changeset/355b75ea7623/ Log: close branch to be merged From pypy.commits at gmail.com Sun Apr 14 02:38:01 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 13 Apr 2019 23:38:01 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged overlapped into py3.6 Message-ID: <5cb2d549.1c69fb81.91404.4ba6@mx.google.com> Author: andrewjlawrence Branch: py3.6 Changeset: r96472:fa2f3d6387d6 Date: 2019-04-14 07:30 +0100 http://bitbucket.org/pypy/pypy/changeset/fa2f3d6387d6/ Log: Merged overlapped into py3.6 diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_overlapped.py @@ -0,0 +1,612 @@ +""" +Support routines for overlapping io. +Currently, this extension module is only required when using the +modules on Windows. +""" + +import sys +if sys.platform != 'win32': + raise ImportError("The '_overlapped' module is only available on Windows") + +# Declare external Win32 functions + +from _pypy_winbase_cffi import ffi as _ffi +_kernel32 = _ffi.dlopen('kernel32') + +_winsock2 = _ffi.dlopen('Ws2_32') + +_mswsock = _ffi.dlopen('Mswsock') + +GetVersion = _kernel32.GetVersion +NULL = _ffi.NULL + +from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z, SetFromWindowsErr +import _winapi + +# +# Error Codes +# +ERROR_IO_PENDING = 997 +ERROR_PIPE_BUSY = 231 +ERROR_NETNAME_DELETED = 64 + +SOCKET_ERROR = -1 + +AF_INET = 2 +AF_INET6 = 23 + +SOCK_STREAM = 1 +IPPROTO_TCP = 6 + +INVALID_SOCKET = -1 + +IOC_OUT = 0x40000000 +IOC_IN = 0x80000000 +IOC_INOUT = IOC_IN | IOC_OUT +IOC_WS2 = 0x08000000 + +def _WSAIORW(x, y): + return IOC_INOUT | x | y + +WSAID_ACCEPTEX = _ffi.new("GUID[1]") +WSAID_ACCEPTEX[0].Data1 = 0xb5367df1 +WSAID_ACCEPTEX[0].Data2 = 0xcbac +WSAID_ACCEPTEX[0].Data3 = 0x11cf +WSAID_ACCEPTEX[0].Data4 = [0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92] + + +WSAID_CONNECTEX = _ffi.new("GUID[1]") +WSAID_CONNECTEX[0].Data1 = 0x25a207b9 +WSAID_CONNECTEX[0].Data2 = 0xddf3 +WSAID_CONNECTEX[0].Data3 = 0x4660 +WSAID_CONNECTEX[0].Data4 = [0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e] + +WSAID_DISCONNECTEX = _ffi.new("GUID[1]") +WSAID_DISCONNECTEX[0].Data1 = 0x7fda2e11 +WSAID_DISCONNECTEX[0].Data2 = 0x8630 +WSAID_DISCONNECTEX[0].Data3 = 0x436f +WSAID_DISCONNECTEX[0].Data4 = [0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57] + +SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6) + +SO_UPDATE_ACCEPT_CONTEXT = 0x700B +SO_UPDATE_CONNECT_CONTEXT = 0x7010 +INADDR_ANY = 0x00000000 +in6addr_any = _ffi.new("struct in6_addr[1]") + +# Status Codes +STATUS_PENDING = 0x00000103 + + +def _int2intptr(int2cast): + return _ffi.cast("ULONG_PTR", int2cast) + +def _int2dword(int2cast): + return _ffi.cast("DWORD", int2cast) + +def _int2handle(val): + return _ffi.cast("HANDLE", val) + +def _int2overlappedptr(val): + return _ffi.cast("OVERLAPPED*", val) + +def _handle2int(handle): + return int(_ffi.cast("intptr_t", handle)) + +from enum import Enum +class OverlappedType(Enum): + TYPE_NONE = 0 + TYPE_NOT_STARTED = 1 + TYPE_READ = 2 + TYPE_READINTO = 3 + TYPE_WRITE = 4 + TYPE_ACCEPT = 5 + TYPE_CONNECT = 6 + TYPE_DISCONNECT = 7 + TYPE_CONNECT_NAMED_PIPE = 8 + TYPE_WAIT_NAMED_PIPE_AND_CONNECT = 9 + TYPE_TRANSMIT_FILE = 10 + +_accept_ex = _ffi.new("AcceptExPtr*") +_connect_ex = _ffi.new("ConnectExPtr*") +_disconnect_ex = _ffi.new("DisconnectExPtr*") + + +def initiailize_function_ptrs(): + ## importing socket ensures that WSAStartup() is called + import _socket + s = _winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + dwBytes = _ffi.new("DWORD[1]", [0]) + if s == INVALID_SOCKET: + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_ACCEPTEX, _ffi.sizeof(WSAID_ACCEPTEX[0]), _accept_ex, \ + _ffi.sizeof(_accept_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + if result == INVALID_SOCKET: + _winsock2.closesocket(s) + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_CONNECTEX, _ffi.sizeof(WSAID_CONNECTEX[0]), _connect_ex, \ + _ffi.sizeof(_connect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + if result == INVALID_SOCKET: + _winsock2.closesocket(s) + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_DISCONNECTEX, _ffi.sizeof(WSAID_DISCONNECTEX[0]), _disconnect_ex, \ + _ffi.sizeof(_disconnect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + + _winsock2.closesocket(s) + if result == INVALID_SOCKET: + raise _winapi._WinError() + + +initiailize_function_ptrs() + + +class Overlapped(object): + def __init__(self, event=_ffi.NULL): + self.overlapped = _ffi.new('OVERLAPPED[1]') + self.handle = _ffi.NULL + self.read_buffer = None + self.write_buffer = None + self.error = 0 + + self.type = OverlappedType.TYPE_NONE + if event == _int2handle(INVALID_HANDLE_VALUE) or not event: + event = _kernel32.CreateEventW(NULL, True, False, NULL) + if event == _winapi.NULL: + raise _winapi._WinError() + + if event: + self.overlapped[0].hEvent = event + else: + raise _winapi._WinError() + + if self.overlapped[0].hEvent == _ffi.NULL: + raise _winapi._WinError() + + def __del__(self): + bytes = _ffi.new("DWORD[1]",[0]) + olderr = _kernel32.GetLastError() + hascompletedio = HasOverlappedIoCompleted(self.overlapped[0]) + if not hascompletedio and self.type != OverlappedType.TYPE_NOT_STARTED: + + wait = _kernel32.CancelIoEx(self.handle, self.overlapped) + ret = self.GetOverlappedResult(wait) + err = _winapi.ERROR_SUCCESS + if not ret: + err = _kernel32.GetLastError() + self.error = err + if err != _winapi.ERROR_SUCCESS and \ + err != _winapi.ERROR_NOT_FOUND and \ + err != _winapi.ERROR_OPERATION_ABORTED: + SetFromWindowsErr(err) + if self.overlapped[0].hEvent != 0: + _winapi.CloseHandle(self.overlapped[0].hEvent) + + @property + def event(self): + return self.overlapped[0].hEvent + + def GetOverlappedResult(self, wait): + transferred = _ffi.new('DWORD[1]', [0]) + + if self.type == OverlappedType.TYPE_NONE: + return _ffi.NULL + + if self.type == OverlappedType.TYPE_NOT_STARTED: + return _ffi.NULL + + res = _kernel32.GetOverlappedResult(self.handle, self.overlapped, transferred, wait != 0) + if res: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + self.error = err + + if err != _winapi.ERROR_SUCCESS and err != _winapi.ERROR_MORE_DATA: + if not (err == _winapi.ERROR_BROKEN_PIPE and (self.type in [OverlappedType.TYPE_READ, OverlappedType.TYPE_READINTO])): + SetFromWindowsErr(err) + + if self.type == OverlappedType.TYPE_READ: + return _ffi.unpack(self.read_buffer, transferred[0]) + else: + return transferred[0] + + def getbuffer(self): + xxx + return None + + def cancel(self): + result = True + if self.type == OverlappedType.TYPE_NOT_STARTED or self.type == OverlappedType.TYPE_WAIT_NAMED_PIPE_AND_CONNECT: + return None + if not HasOverlappedIoCompleted(self.overlapped[0]): + ### If we are to support xp we will need to dynamically load the below method + result = _kernel32.CancelIoEx(self.handle, self.overlapped) + if (not result and _kernel32.GetLastError() != _winapi.ERROR_NOT_FOUND): + SetFromWindowsErr(0) + + def WSARecv(self ,handle, size, flags): + handle = _int2handle(handle) + flags = _int2dword(flags) + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + self.type = OverlappedType.TYPE_READ + self.handle = _int2handle(handle) + self.read_buffer = _ffi.new("CHAR[]", max(1,size)) + return self.do_WSARecv(handle, self.read_buffer, size, flags) + + def do_WSARecv(self, handle, allocatedbuffer, size, flags): + nread = _ffi.new("LPDWORD") + wsabuff = _ffi.new("WSABUF[1]") + buffercount = _ffi.new("DWORD[1]", [1]) + pflags = _ffi.new("LPDWORD") + pflags[0] = flags + + wsabuff[0].len = size + wsabuff[0].buf = allocatedbuffer + + result = _winsock2.WSARecv(handle, wsabuff, _int2dword(1), nread, pflags, self.overlapped, _ffi.NULL) + if result == SOCKET_ERROR: + self.error = _kernel32.GetLastError() + else: + self.error = _winapi.ERROR_SUCCESS + + if self.error == _winapi.ERROR_BROKEN_PIPE: + mark_as_completed(self.overlapped) + SetFromWindowsErr(self.error) + elif self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING] : + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def WSASend(self ,handle, bufobj, flags): + handle = _int2handle(handle) + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + self.write_buffer = bufobj + self.type = OverlappedType.TYPE_WRITE + self.handle = handle + + wsabuff = _ffi.new("WSABUF[1]") + wsabuff[0].len = len(bufobj) + wsabuff[0].buf = _ffi.new("CHAR[]", bufobj) + nwritten = _ffi.new("LPDWORD") + + result = _winsock2.WSASend(handle, wsabuff, _int2dword(1), nwritten, flags, self.overlapped, _ffi.NULL) + + if result == SOCKET_ERROR: + self.error = _kernel32.GetLastError() + else: + self.error = _winapi.ERROR_SUCCESS + + if self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_IO_PENDING]: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def getresult(self, wait=False): + return self.GetOverlappedResult(wait) + + def ConnectNamedPipe(self, handle): + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + self.type = OverlappedType.TYPE_CONNECT_NAMED_PIPE + self.handle = _int2handle(handle) + success = _kernel32.ConnectNamedPipe(self.handle, self.overlapped) + + if success: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + self.error = err + + if err == _winapi.ERROR_IO_PENDING | _winapi.ERROR_SUCCESS: + return False + elif err == _winapi.ERROR_PIPE_CONNECTED: + mark_as_completed(self.overlapped) + return True + else: + SetFromWindowsErr(err) + + def ReadFile(self, handle, size): + self.type = OverlappedType.TYPE_READ + self.handle = _int2handle(handle) + self.read_buffer = _ffi.new("CHAR[]", max(1,size)) + return self.do_ReadFile(self.handle, self.read_buffer, size) + + def do_ReadFile(self, handle, buf, size): + nread = _ffi.new('DWORD[1]', [0]) + ret = _kernel32.ReadFile(handle, buf, size, nread, self.overlapped) + if ret: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + + self.error = err + + if err == _winapi.ERROR_BROKEN_PIPE: + mark_as_completed(self.overlapped) + SetFromWindowsErr(err) + elif err in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING]: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(err) + + def WriteFile(self, handle, buffer): + self.handle = _int2handle(handle) + self.write_buffer = buffer + written = _ffi.new('DWORD[1]', [0]) + + # Check if we have already performed some IO + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + self.type = OverlappedType.TYPE_WRITE + + ret = _kernel32.WriteFile(self.handle, self.write_buffer, len(self.write_buffer), written, self.overlapped) + + if ret: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def AcceptEx(self, listensocket, acceptsocket): + listensocket = _int2handle(listensocket) + acceptsocket = _int2handle(acceptsocket) + bytesreceived = _ffi.new("DWORD[1]") + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + size = _ffi.sizeof("struct sockaddr_in6") + 16 + buf = _ffi.new("CHAR[]", size*2) + if not buf: + return None + + self.type = OverlappedType.TYPE_ACCEPT + self.handle = listensocket + self.read_buffer = buf + + res = _accept_ex[0](listensocket, acceptsocket, buf, \ + 0, size, size, bytesreceived, self.overlapped) + + if res: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(0) + + def DisconnectEx(self, socket, flags): + xxx + return None + + def ConnectEx(self, socket, addressobj): + socket = _int2handle(socket) + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + address = _ffi.new("struct sockaddr_in6*") + length = _ffi.sizeof("struct sockaddr_in6") + + address, length = parse_address(addressobj, _ffi.cast("SOCKADDR*",address), length) + + if length < 0: + return None + + self.type = OverlappedType.TYPE_CONNECT + self.handle = socket + + res = _connect_ex[0](socket, address, length, \ + _ffi.NULL, 0, _ffi.NULL, self.overlapped) + + if res: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(0) + + @property + def pending(self): + return (not HasOverlappedIoCompleted(self.overlapped[0]) and + self.type != OverlappedType.TYPE_NOT_STARTED) + + @property + def address(self): + return _handle2int(self.overlapped) + +def SetEvent(handle): + ret = _kernel32.SetEvent(_int2handle(handle)) + if not ret: + raise _winapi._WinError() + +def mark_as_completed(overlapped): + overlapped[0].Internal = 0 + if overlapped[0].hEvent != _ffi.NULL: + SetEvent(overlapped[0].hEvent) + +def CreateEvent(eventattributes, manualreset, initialstate, name): + event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name)) + event = _handle2int(event) + if not event: + raise _winapi._WinError() + return event + +def CreateIoCompletionPort(handle, existingcompletionport, completionkey, numberofconcurrentthreads): + completionkey = _int2intptr(completionkey) + existingcompletionport = _int2handle(existingcompletionport) + numberofconcurrentthreads = _int2dword(numberofconcurrentthreads) + handle = _int2handle(handle) + result = _kernel32.CreateIoCompletionPort(handle, + existingcompletionport, + completionkey, + numberofconcurrentthreads) + if result == _ffi.NULL: + raise SetFromWindowsErr(0) + return _handle2int(result) + +def PostQueuedCompletionStatus(completionport, ms): + raise _winapi._WinError() + +def GetQueuedCompletionStatus(completionport, milliseconds): + numberofbytes = _ffi.new('DWORD[1]', [0]) + completionkey = _ffi.new('ULONG**') + completionport = _int2handle(completionport) + + if completionport is None: + raise _winapi._WinError() + overlapped = _ffi.new("OVERLAPPED**") + overlapped[0] = _ffi.NULL + result = _kernel32.GetQueuedCompletionStatus(completionport, + numberofbytes, + completionkey, + overlapped, + milliseconds) + if result: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + + if overlapped[0] == _ffi.NULL: + if err == _winapi.WAIT_TIMEOUT: + return None + return SetFromWindowsErr(err) + + return (err, numberofbytes, _handle2int(completionkey[0]), _handle2int(_ffi.addressof(overlapped[0][0]))) + + at _ffi.callback("void(void*, int)") +def post_to_queue_callback(lpparameter, timerorwaitfired): + pdata = _ffi.cast("PostCallbackData*", lpparameter) + ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, timerorwaitfired, _ffi.cast("ULONG_PTR",0), pdata.Overlapped) + result = False + _winapi.free(pdata) + + +def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds): + data = _ffi.cast('PostCallbackData*', _winapi.malloc( _ffi.sizeof("PostCallbackData"))) + newwaitobject = _ffi.new("HANDLE*") + data[0].hCompletionPort = _int2handle(completionport) + data[0].Overlapped = _int2overlappedptr(ovaddress) + ret = _kernel32.RegisterWaitForSingleObject(newwaitobject, + _int2handle(object), + _ffi.cast("WAITORTIMERCALLBACK",post_to_queue_callback), + data, + miliseconds, + _kernel32.WT_EXECUTEINWAITTHREAD | _kernel32.WT_EXECUTEONLYONCE) + if not ret: + SetFromWindowsErr(0) + + return _handle2int(newwaitobject[0]) + +def ConnectPipe(address): + err = _winapi.ERROR_PIPE_BUSY + waddress = _ffi.new("wchar_t[]", address) + handle = _kernel32.CreateFileW(waddress, + _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, + 0, + _ffi.NULL, + _winapi.OPEN_EXISTING, + _winapi.FILE_FLAG_OVERLAPPED, + _ffi.NULL) + err = _kernel32.GetLastError() + + if handle == INVALID_HANDLE_VALUE or err == _winapi.ERROR_PIPE_BUSY: + SetFromWindowsErr(err) + + return _handle2int(handle) + +def UnregisterWaitEx(handle, event): + waithandle = _int2handle(handle) + waitevent = _int2handle(event) + + ret = _kernel32.UnregisterWaitEx(waithandle, waitevent) + + if not ret: + SetFromWindowsErr(0) + +def UnregisterWait(handle): + handle = _int2handle(handle) + + ret = _kernel32.UnregisterWait(handle) + + if not ret: + SetFromWindowsErr(0) + +def BindLocal(socket, family): + socket = _int2handle(socket) + if family == AF_INET: + addr = _ffi.new("struct sockaddr_in*") + addr[0].sin_family = AF_INET + addr[0].sin_port = 0 + addr[0].sin_addr.S_un.S_addr = INADDR_ANY + paddr = _ffi.cast("PSOCKADDR", addr) + result = _winsock2.bind(socket, paddr, _ffi.sizeof("struct sockaddr_in")) + elif family == AF_INET6: + addr = _ffi.new("struct sockaddr_in6*") + addr.sin6_family = AF_INET6 + addr.sin6_port = 0 + addr.sin6_addr = in6addr_any[0] + result = _winsock2.bind(socket, _ffi.cast("PSOCKADDR", addr), _ffi.sizeof("struct sockaddr_in")) + else: + raise ValueError() + + if result == SOCKET_ERROR: + SetFromWindowsErr(0) + +def HasOverlappedIoCompleted(overlapped): + return (overlapped.Internal != STATUS_PENDING) + +def parse_address(addressobj, address, length): + lengthptr = _ffi.new("INT*") + lengthptr[0] = length + if len(addressobj) == 2: + host,port = addressobj + address[0].sa_family = AF_INET + result = _winsock2.WSAStringToAddressW(host, AF_INET, _ffi.NULL, address, lengthptr) + if result < 0: + raise _winapi.WinError() + _ffi.cast("SOCKADDR_IN*",address)[0].sin_port = _winsock2.htons(port) + return address, lengthptr[0] + elif len(addressobj) == 4: + host, port, flowinfo, scopeid = addressobj + address.sa_family = AF_INET6 + result = _winsock2.WSAStringToAddressW(host, AF_INET6, _ffi.NULL, address, lengthptr) + address.sin6_port = _winsock2.htons(port) + address.sin6_flowinfo = flowinfo + address.sin6_scopeid = scopeid + return address, lengthptr[0] + else: + return -1 + + + + + + + diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -90,7 +90,6 @@ HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED; - DWORD WINAPI GetVersion(void); BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, void *, DWORD); HANDLE WINAPI CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD, @@ -101,16 +100,17 @@ DWORD, DWORD, HANDLE); HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD); BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED); HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR); HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR); -VOID WINAPI SetEvent(HANDLE); +BOOL WINAPI SetEvent(HANDLE); +BOOL WINAPI CancelIo(HANDLE); BOOL WINAPI CancelIoEx(HANDLE, LPOVERLAPPED); BOOL WINAPI CloseHandle(HANDLE); DWORD WINAPI GetLastError(VOID); BOOL WINAPI GetOverlappedResult(HANDLE, LPOVERLAPPED, LPDWORD, BOOL); - HANDLE WINAPI GetCurrentProcess(void); BOOL WINAPI DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD); @@ -121,19 +121,171 @@ void *, BOOL, DWORD, wchar_t *, wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION); DWORD WINAPI WaitForSingleObject(HANDLE, DWORD); +DWORD WaitForMultipleObjects(DWORD, HANDLE*, BOOL, DWORD); BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD); BOOL WINAPI TerminateProcess(HANDLE, UINT); HANDLE WINAPI GetStdHandle(DWORD); DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD); - UINT WINAPI SetErrorMode(UINT); #define SEM_FAILCRITICALERRORS 0x0001 #define SEM_NOGPFAULTERRORBOX 0x0002 #define SEM_NOALIGNMENTFAULTEXCEPT 0x0004 #define SEM_NOOPENFILEERRORBOX 0x8000 + +typedef struct _PostCallbackData { + HANDLE hCompletionPort; + LPOVERLAPPED Overlapped; +} PostCallbackData, *LPPostCallbackData; + +typedef VOID (WINAPI *WAITORTIMERCALLBACK) (PVOID, BOOL); +BOOL WINAPI RegisterWaitForSingleObject(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, ULONG, ULONG); + +BOOL WINAPI PostQueuedCompletionStatus(HANDLE, DWORD, ULONG_PTR, LPOVERLAPPED); +BOOL WINAPI UnregisterWaitEx(HANDLE, HANDLE); +BOOL WINAPI UnregisterWait(HANDLE); + +BOOL WINAPI GetQueuedCompletionStatus(HANDLE, LPDWORD, ULONG**, LPOVERLAPPED*, DWORD); +HANDLE WINAPI CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD); + +BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); + +#define WT_EXECUTEINWAITTHREAD 0x00000004 +#define WT_EXECUTEONLYONCE 0x00000008 + +HANDLE GetProcessHeap(); +LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T); +BOOL HeapFree(HANDLE, DWORD, LPVOID); + """) -# -------------------- +# -------------------- Win Sock 2 ---------------------- + +ffi.cdef(""" +typedef struct _WSABUF { + ULONG len; + CHAR *buf; +} WSABUF, *LPWSABUF; + +typedef HANDLE SOCKET; +SOCKET __stdcall socket(int, int, int); +int closesocket(SOCKET); + + +typedef BOOL (__stdcall * LPFN_DISCONNECTEX) (SOCKET, LPOVERLAPPED, DWORD, DWORD); +typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE) (DWORD, DWORD, LPVOID); + +int __stdcall WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); +int __stdcall WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); +int __stdcall WSAIoctl(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); + + +typedef struct _GUID { + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[8]; +} GUID; + +typedef USHORT ADDRESS_FAMILY; + +typedef struct in6_addr { + union { + UCHAR Byte[16]; + USHORT Word[8]; + } u; +} IN6_ADDR, *PIN6_ADDR, *LPIN6_ADDR; + +typedef struct { + union { + struct { + ULONG Zone : 28; + ULONG Level : 4; + }; + ULONG Value; + }; +} SCOPE_ID, *PSCOPE_ID; + +typedef struct sockaddr_in6 { + ADDRESS_FAMILY sin6_family; + USHORT sin6_port; + ULONG sin6_flowinfo; + IN6_ADDR sin6_addr; + union { + ULONG sin6_scope_id; + SCOPE_ID sin6_scope_struct; + }; +} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH; + +typedef struct in_addr { + union { + struct { + UCHAR s_b1; + UCHAR s_b2; + UCHAR s_b3; + UCHAR s_b4; + } S_un_b; + struct { + USHORT s_w1; + USHORT s_w2; + } S_un_w; + ULONG S_addr; + } S_un; +} INADDR, *PINADDR; + +typedef struct sockaddr_in { + SHORT sin_family; + USHORT sin_port; + INADDR sin_addr; + CHAR sin_zero[8]; +} SOCKADDR_IN, *PSOCKADDR_IN, *LPSOCKADDR_IN; + +typedef struct sockaddr { + USHORT sa_family; + CHAR sa_data[14]; +} SOCKADDR, *PSOCKADDR, *LPSOCKADDR; + +int bind(SOCKET, const PSOCKADDR, int); + +#define MAX_PROTOCOL_CHAIN 7 + +typedef struct _WSAPROTOCOLCHAIN { + int ChainLen; + DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; +} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN; + +#define WSAPROTOCOL_LEN 255 + +typedef struct _WSAPROTOCOL_INFOW { + DWORD dwServiceFlags1; + DWORD dwServiceFlags2; + DWORD dwServiceFlags3; + DWORD dwServiceFlags4; + DWORD dwProviderFlags; + GUID ProviderId; + DWORD dwCatalogEntryId; + WSAPROTOCOLCHAIN ProtocolChain; + int iVersion; + int iAddressFamily; + int iMaxSockAddr; + int iMinSockAddr; + int iSocketType; + int iProtocol; + int iProtocolMaxOffset; + int iNetworkByteOrder; + int iSecurityScheme; + DWORD dwMessageSize; + DWORD dwProviderReserved; + WCHAR szProtocol[WSAPROTOCOL_LEN + 1]; +} WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW; + +int __stdcall WSAStringToAddressW(LPWSTR, int, LPWSAPROTOCOL_INFOW, LPSOCKADDR, int* ); + +typedef BOOL (WINAPI* AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const PSOCKADDR, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *DisconnectExPtr)(SOCKET, LPOVERLAPPED, DWORD, DWORD); + +USHORT htons(USHORT); +""") if __name__ == "__main__": ffi.compile() diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py --- a/lib_pypy/_pypy_winbase_cffi.py +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -3,8 +3,8 @@ ffi = _cffi_backend.FFI('_pypy_winbase_cffi', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xAB\x03\x00\x00\x13\x11\x00\x00\xB0\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\xAA\x03\x00\x00\xA8\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\xA7\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x29\x11\x00\x00\x18\x03\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x6B\x03\x00\x00\x49\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x33\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x66\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\xA9\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xAB\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x6E\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6B\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x77\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\xB0\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x04\x09\x00\x00\x02\x09\x00\x00\x05\x09\x00\x00\x03\x09\x00\x00\x02\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\xAF\x03\x00\x00\x04\x01\x00\x00\x00\x01', - _globals = (b'\x00\x00\x27\x23CancelIoEx',0,b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x27\x23ConnectNamedPipe',0,b'\x00\x00\x6D\x23CreateEventA',0,b'\x00\x00\x73\x23CreateEventW',0,b'\x00\x00\x79\x23CreateFileA',0,b'\x00\x00\x9B\x23CreateFileW',0,b'\x00\x00\x82\x23CreateNamedPipeA',0,b'\x00\x00\x91\x23CreateNamedPipeW',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x48\x23CreateProcessW',0,b'\x00\x00\x3F\x23DuplicateHandle',0,b'\x00\x00\x8F\x23GetCurrentProcess',0,b'\x00\x00\x35\x23GetExitCodeProcess',0,b'\x00\x00\x63\x23GetLastError',0,b'\x00\x00\x5E\x23GetModuleFileNameW',0,b'\x00\x00\x2B\x23GetOverlappedResult',0,b'\x00\x00\x8C\x23GetStdHandle',0,b'\x00\x00\x63\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x57\x23SetErrorMode',0,b'\x00\x00\xA4\x23SetEvent',0,b'\x00\x00\x39\x23SetNamedPipeHandleState',0,b'\x00\x00\x31\x23TerminateProcess',0,b'\x00\x00\x5A\x23WaitForSingleObject',0,b'\x00\x00\x54\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x68\x23_getwch',0,b'\x00\x00\x68\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x6A\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x65\x23_ungetwch',0), - _struct_unions = ((b'\x00\x00\x00\xAD\x00\x00\x00\x03$1',b'\x00\x00\xAC\x11DUMMYSTRUCTNAME',b'\x00\x00\x15\x11Pointer'),(b'\x00\x00\x00\xAC\x00\x00\x00\x02$2',b'\x00\x00\x18\x11Offset',b'\x00\x00\x18\x11OffsetHigh'),(b'\x00\x00\x00\xA8\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\xAA\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x66\x11wShowWindow',b'\x00\x00\x66\x11cbReserved2',b'\x00\x00\xAE\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError'),(b'\x00\x00\x00\xA7\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x18\x11Internal',b'\x00\x00\x18\x11InternalHigh',b'\x00\x00\xAD\x11DUMMYUNIONNAME',b'\x00\x00\x15\x11hEvent'),(b'\x00\x00\x00\xA9\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x18\x11nLength',b'\x00\x00\x15\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle')), - _typenames = (b'\x00\x00\x00\x29LPOVERLAPPED',b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x6ELPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\xA7OVERLAPPED',b'\x00\x00\x00\xA8PROCESS_INFORMATION',b'\x00\x00\x00\x6EPSECURITY_ATTRIBUTES',b'\x00\x00\x00\xA9SECURITY_ATTRIBUTES',b'\x00\x00\x00\xAASTARTUPINFO',b'\x00\x00\x00\x66wint_t'), + _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x68\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x42\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x3B\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x4C\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x47\x03\x00\x01\x3C\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x32\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x48\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x2D\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x68\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xE2\x03\x00\x00\x07\x01\x00\x01\x4B\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xDD\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x41\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x4C\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEC\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xE2\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF5\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x68\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x68\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x38\x03\x00\x00\x13\x09\x00\x01\x3A\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x3E\x03\x00\x00\x0E\x09\x00\x01\x40\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x46\x03\x00\x01\x45\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x4A\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x4C\x05\x00\x00\x00\x0E\x00\x01\x4C\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\x98\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x5F\x03\x00\x00\x04\x01\x00\x01\x5F\x05\x00\x00\x00\x10\x00\x01\x5F\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xDD\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xE2\x05\x00\x00\x01\x00', + _globals = (b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xEB\x23CreateEventA',0,b'\x00\x00\xF1\x23CreateEventW',0,b'\x00\x00\xF7\x23CreateFileA',0,b'\x00\x01\x24\x23CreateFileW',0,b'\x00\x01\x12\x23CreateIoCompletionPort',0,b'\x00\x01\x00\x23CreateNamedPipeA',0,b'\x00\x01\x1A\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xB9\x23CreateProcessW',0,b'\x00\x00\xA2\x23DuplicateHandle',0,b'\x00\x01\x18\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xDA\x23GetLastError',0,b'\x00\x00\xD5\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xE9\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x0F\x23GetStdHandle',0,b'\x00\x00\xDA\x23GetVersion',0,b'\x00\x00\xE4\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC8\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xB2\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xCB\x23WaitForMultipleObjects',0,b'\x00\x00\xD1\x23WaitForSingleObject',0,b'\x00\x00\xAB\x23WriteFile',0,b'\x00\x00\xC5\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xDF\x23_getwch',0,b'\x00\x00\xDF\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE1\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xDC\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xDC\x23htons',0,b'\x00\x01\x0A\x23socket',0), + _struct_unions = ((b'\x00\x00\x01\x59\x00\x00\x00\x03$1',b'\x00\x01\x55\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x55\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x5A\x00\x00\x00\x03$3',b'\x00\x01\x60\x11Byte',b'\x00\x01\x66\x11Word'),(b'\x00\x00\x01\x5B\x00\x00\x00\x01$4',b'\x00\x01\x56\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x56\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x5C\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x40\x11sin6_scope_struct'),(b'\x00\x00\x01\x5D\x00\x00\x00\x03$7',b'\x00\x01\x57\x11S_un_b',b'\x00\x01\x58\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x57\x00\x00\x00\x02$8',b'\x00\x01\x5F\x11s_b1',b'\x00\x01\x5F\x11s_b2',b'\x00\x01\x5F\x11s_b3',b'\x00\x01\x5F\x11s_b4'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$9',b'\x00\x00\xDD\x11s_w1',b'\x00\x00\xDD\x11s_w2'),(b'\x00\x00\x01\x3C\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x40\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x5B\x11'),(b'\x00\x00\x01\x47\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xDD\x11wShowWindow',b'\x00\x00\xDD\x11cbReserved2',b'\x00\x01\x5E\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x36\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xDD\x11Data2',b'\x00\x00\xDD\x11Data3',b'\x00\x01\x62\x11Data4'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x59\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x41\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x64\x11ChainEntries'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x36\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x4A\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x69\x11szProtocol'),(b'\x00\x00\x01\x38\x00\x00\x00\x02in6_addr',b'\x00\x01\x5A\x11u'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02in_addr',b'\x00\x01\x5D\x11S_un'),(b'\x00\x00\x01\x42\x00\x00\x00\x02sockaddr',b'\x00\x00\xDD\x11sa_family',b'\x00\x01\x4D\x11sa_data'),(b'\x00\x00\x01\x46\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x54\x11sin_family',b'\x00\x00\xDD\x11sin_port',b'\x00\x01\x3A\x11sin_addr',b'\x00\x01\x4F\x11sin_zero'),(b'\x00\x00\x01\x45\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xDD\x11sin6_family',b'\x00\x00\xDD\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x38\x11sin6_addr',b'\x00\x01\x5C\x11')), + _typenames = (b'\x00\x00\x00\xDDADDRESS_FAMILY',b'\x00\x00\x01\x53AcceptExPtr',b'\x00\x00\x01\x52ConnectExPtr',b'\x00\x00\x01\x51DisconnectExPtr',b'\x00\x00\x01\x36GUID',b'\x00\x00\x01\x38IN6_ADDR',b'\x00\x00\x01\x3AINADDR',b'\x00\x00\x01\x51LPFN_DISCONNECTEX',b'\x00\x00\x01\x37LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x3DLPPostCallbackData',b'\x00\x00\x00\xECLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x43LPSOCKADDR_IN',b'\x00\x00\x01\x44LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x49LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB5LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x3BOVERLAPPED',b'\x00\x00\x01\x37PIN6_ADDR',b'\x00\x00\x01\x39PINADDR',b'\x00\x00\x01\x3CPROCESS_INFORMATION',b'\x00\x00\x01\x3FPSCOPE_ID',b'\x00\x00\x00\xECPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x43PSOCKADDR_IN',b'\x00\x00\x01\x44PSOCKADDR_IN6_LH',b'\x00\x00\x01\x3EPostCallbackData',b'\x00\x00\x01\x40SCOPE_ID',b'\x00\x00\x01\x41SECURITY_ATTRIBUTES',b'\x00\x00\x01\x42SOCKADDR',b'\x00\x00\x01\x46SOCKADDR_IN',b'\x00\x00\x01\x45SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x47STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x48WSABUF',b'\x00\x00\x01\x4AWSAPROTOCOLCHAIN',b'\x00\x00\x01\x4BWSAPROTOCOL_INFOW',b'\x00\x00\x00\xDDwint_t'), ) diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -17,10 +17,25 @@ NULL = _ffi.NULL # Now the _subprocess module implementation +def _WinError(type=WindowsError): + code, message = _ffi.getwinerror() + excep = type(None, message, None ,code) + raise excep -def _WinError(): - code, message = _ffi.getwinerror() - raise WindowsError(code, message) +# In CPython this function converts a windows error into a python object +# Not sure what we should do here. +def SetFromWindowsErr(err): + if err == 0: + err = _kernel32.GetLastError() + + if err == ERROR_CONNECTION_REFUSED: + type = ConnectionRefusedError + elif err == ERROR_CONNECTION_ABORTED: + type = ConnectionAbortedError + else: + type = WindowsError + + return _WinError(type) def _int2handle(val): return _ffi.cast("HANDLE", val) @@ -32,25 +47,25 @@ def CreatePipe(attributes, size): handles = _ffi.new("HANDLE[2]") - + res = _kernel32.CreatePipe(handles, handles + 1, NULL, size) if not res: - raise _WinError() + SetFromWindowsErr(0) return _handle2int(handles[0]), _handle2int(handles[1]) def CreateNamedPipe(*args): handle = _kernel32.CreateNamedPipeW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() - return handle + SetFromWindowsErr(0) + return _handle2int(handle) def CreateFile(*args): handle = _kernel32.CreateFileW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() - return handle + SetFromWindowsErr(0) + return _handle2int(handle) def SetNamedPipeHandleState(namedpipe, mode, max_collection_count, collect_data_timeout): d0 = _ffi.new('DWORD[1]', [mode]) @@ -79,20 +94,20 @@ def __del__(self): # do this somehow else - xxx err = _kernel32.GetLastError() bytes = _ffi.new('DWORD[1]') - o = overlapped[0] - if overlapped[0].pending: + o = self.overlapped[0] + if self.pending: if _kernel32.CancelIoEx(o.handle, o.overlapped) & \ self.GetOverlappedResult(o.handle, o.overlapped, _ffi.addressof(bytes), True): # The operation is no longer pending, nothing to do pass else: - raise RuntimeError('deleting an overlapped strucwith a pending operation not supported') + raise RuntimeError('deleting an overlapped struct with a pending operation not supported') @property def event(self): + xxx return None def GetOverlappedResult(self, wait): @@ -110,8 +125,8 @@ else: self.pending = 0 raise _WinError() - if self.completed and self.read_buffer: - if transferred != len(self.read_buffer): + if self.completed and self.readbuffer: + if transferred != len(self.readbuffer): raise _WinError() return transferred[0], err @@ -125,6 +140,7 @@ def ConnectNamedPipe(handle, overlapped=False): + handle = _int2handle(handle) if overlapped: ov = Overlapped(handle) else: @@ -140,10 +156,10 @@ _kernel32.SetEvent(ov.overlapped[0].hEvent) else: del ov - raise _WinError() + SetFromWindowsErr(err) return ov elif not success: - raise _WinError() + SetFromWindowsErr(0) def GetCurrentProcess(): return _handle2int(_kernel32.GetCurrentProcess()) @@ -217,6 +233,18 @@ return res +def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds): + if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS: + return None + + # CPython makes the wait interruptible by ctrl-c. We need to add this in at some point + res = _kernel32.WaitForMultipleObjects(len(handle_sequence), handle_sequence, waitflag, milliseconds) + + if res == WAIT_FAILED: + raise _WinError() + return int(res) + + def GetExitCodeProcess(handle): # CPython: the first argument is expected to be an integer. code = _ffi.new("DWORD[1]") @@ -260,6 +288,14 @@ raise _WinError() return _ffi.string(buf) +ZERO_MEMORY = 0x00000008 + +def malloc(size): + return _kernel32.HeapAlloc(_kernel32.GetProcessHeap(),ZERO_MEMORY,size) + +def free(voidptr): + _kernel32.HeapFree(_kernel32.GetProcessHeap(),0, voidptr) + # #define macros from WinBase.h and elsewhere STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 @@ -272,6 +308,7 @@ WAIT_OBJECT_0 = 0 WAIT_ABANDONED_0 = 0x80 WAIT_TIMEOUT = 0x102 +WAIT_FAILED = 0xFFFFFFFF CREATE_NEW_CONSOLE = 0x010 CREATE_NEW_PROCESS_GROUP = 0x200 CREATE_UNICODE_ENVIRONMENT = 0x400 @@ -281,11 +318,14 @@ ERROR_SUCCESS = 0 ERROR_NETNAME_DELETED = 64 ERROR_BROKEN_PIPE = 109 +ERROR_PIPE_BUSY = 231 ERROR_MORE_DATA = 234 ERROR_PIPE_CONNECTED = 535 ERROR_OPERATION_ABORTED = 995 ERROR_IO_INCOMPLETE = 996 ERROR_IO_PENDING = 997 +ERROR_CONNECTION_REFUSED = 1225 +ERROR_CONNECTION_ABORTED = 1236 PIPE_ACCESS_INBOUND = 0x00000001 PIPE_ACCESS_OUTBOUND = 0x00000002 @@ -299,11 +339,13 @@ PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000 PIPE_REJECT_REMOTE_CLIENTS = 0x00000008 +PIPE_UNLIMITED_INSTANCES = 255 + GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 GENERIC_EXECUTE= 0x20000000 GENERIC_ALL = 0x10000000 -INVALID_HANDLE_VALUE = -1 +INVALID_HANDLE_VALUE = _int2handle(-1) FILE_FLAG_WRITE_THROUGH = 0x80000000 FILE_FLAG_OVERLAPPED = 0x40000000 FILE_FLAG_NO_BUFFERING = 0x20000000 @@ -326,3 +368,5 @@ OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 +MAXIMUM_WAIT_OBJECTS = 64 + diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -8,3 +8,8 @@ .. branch: zlib-make-py3-go-boom Complain if you try to copy a flushed zlib decompress on py3 + +.. branch: winoverlapped + +Add support for async (overlapped) IO on Windows. + diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -261,7 +261,7 @@ 132: 13, 145: 41, 158: 13, 161: 2, 164: 11, 167: 13, 183: 17, 188: 8, 189: 8, 190: 8, 191: 8, 192: 8, 193: 8, 194: 8, 195: 8, 196: 8, 197: 8, 198: 8, 199: 8, 200: 8, 201: 8, - 202: 8, 206: 2, 215: 11, 232: 32, 267: 20, 1816: 12, 1225: 111, + 202: 8, 206: 2, 215: 11, 232: 32, 267: 20, 1816: 12, } return errors, errno.EINVAL From pypy.commits at gmail.com Sun Apr 14 02:38:03 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 13 Apr 2019 23:38:03 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged heads. Message-ID: <5cb2d54b.1c69fb81.8765b.4ec3@mx.google.com> Author: andrewjlawrence Branch: py3.6 Changeset: r96473:db5a1e7fbbd0 Date: 2019-04-14 07:36 +0100 http://bitbucket.org/pypy/pypy/changeset/db5a1e7fbbd0/ Log: Merged heads. diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_overlapped.py @@ -0,0 +1,612 @@ +""" +Support routines for overlapping io. +Currently, this extension module is only required when using the +modules on Windows. +""" + +import sys +if sys.platform != 'win32': + raise ImportError("The '_overlapped' module is only available on Windows") + +# Declare external Win32 functions + +from _pypy_winbase_cffi import ffi as _ffi +_kernel32 = _ffi.dlopen('kernel32') + +_winsock2 = _ffi.dlopen('Ws2_32') + +_mswsock = _ffi.dlopen('Mswsock') + +GetVersion = _kernel32.GetVersion +NULL = _ffi.NULL + +from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z, SetFromWindowsErr +import _winapi + +# +# Error Codes +# +ERROR_IO_PENDING = 997 +ERROR_PIPE_BUSY = 231 +ERROR_NETNAME_DELETED = 64 + +SOCKET_ERROR = -1 + +AF_INET = 2 +AF_INET6 = 23 + +SOCK_STREAM = 1 +IPPROTO_TCP = 6 + +INVALID_SOCKET = -1 + +IOC_OUT = 0x40000000 +IOC_IN = 0x80000000 +IOC_INOUT = IOC_IN | IOC_OUT +IOC_WS2 = 0x08000000 + +def _WSAIORW(x, y): + return IOC_INOUT | x | y + +WSAID_ACCEPTEX = _ffi.new("GUID[1]") +WSAID_ACCEPTEX[0].Data1 = 0xb5367df1 +WSAID_ACCEPTEX[0].Data2 = 0xcbac +WSAID_ACCEPTEX[0].Data3 = 0x11cf +WSAID_ACCEPTEX[0].Data4 = [0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92] + + +WSAID_CONNECTEX = _ffi.new("GUID[1]") +WSAID_CONNECTEX[0].Data1 = 0x25a207b9 +WSAID_CONNECTEX[0].Data2 = 0xddf3 +WSAID_CONNECTEX[0].Data3 = 0x4660 +WSAID_CONNECTEX[0].Data4 = [0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e] + +WSAID_DISCONNECTEX = _ffi.new("GUID[1]") +WSAID_DISCONNECTEX[0].Data1 = 0x7fda2e11 +WSAID_DISCONNECTEX[0].Data2 = 0x8630 +WSAID_DISCONNECTEX[0].Data3 = 0x436f +WSAID_DISCONNECTEX[0].Data4 = [0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57] + +SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6) + +SO_UPDATE_ACCEPT_CONTEXT = 0x700B +SO_UPDATE_CONNECT_CONTEXT = 0x7010 +INADDR_ANY = 0x00000000 +in6addr_any = _ffi.new("struct in6_addr[1]") + +# Status Codes +STATUS_PENDING = 0x00000103 + + +def _int2intptr(int2cast): + return _ffi.cast("ULONG_PTR", int2cast) + +def _int2dword(int2cast): + return _ffi.cast("DWORD", int2cast) + +def _int2handle(val): + return _ffi.cast("HANDLE", val) + +def _int2overlappedptr(val): + return _ffi.cast("OVERLAPPED*", val) + +def _handle2int(handle): + return int(_ffi.cast("intptr_t", handle)) + +from enum import Enum +class OverlappedType(Enum): + TYPE_NONE = 0 + TYPE_NOT_STARTED = 1 + TYPE_READ = 2 + TYPE_READINTO = 3 + TYPE_WRITE = 4 + TYPE_ACCEPT = 5 + TYPE_CONNECT = 6 + TYPE_DISCONNECT = 7 + TYPE_CONNECT_NAMED_PIPE = 8 + TYPE_WAIT_NAMED_PIPE_AND_CONNECT = 9 + TYPE_TRANSMIT_FILE = 10 + +_accept_ex = _ffi.new("AcceptExPtr*") +_connect_ex = _ffi.new("ConnectExPtr*") +_disconnect_ex = _ffi.new("DisconnectExPtr*") + + +def initiailize_function_ptrs(): + ## importing socket ensures that WSAStartup() is called + import _socket + s = _winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + dwBytes = _ffi.new("DWORD[1]", [0]) + if s == INVALID_SOCKET: + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_ACCEPTEX, _ffi.sizeof(WSAID_ACCEPTEX[0]), _accept_ex, \ + _ffi.sizeof(_accept_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + if result == INVALID_SOCKET: + _winsock2.closesocket(s) + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_CONNECTEX, _ffi.sizeof(WSAID_CONNECTEX[0]), _connect_ex, \ + _ffi.sizeof(_connect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + if result == INVALID_SOCKET: + _winsock2.closesocket(s) + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_DISCONNECTEX, _ffi.sizeof(WSAID_DISCONNECTEX[0]), _disconnect_ex, \ + _ffi.sizeof(_disconnect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + + _winsock2.closesocket(s) + if result == INVALID_SOCKET: + raise _winapi._WinError() + + +initiailize_function_ptrs() + + +class Overlapped(object): + def __init__(self, event=_ffi.NULL): + self.overlapped = _ffi.new('OVERLAPPED[1]') + self.handle = _ffi.NULL + self.read_buffer = None + self.write_buffer = None + self.error = 0 + + self.type = OverlappedType.TYPE_NONE + if event == _int2handle(INVALID_HANDLE_VALUE) or not event: + event = _kernel32.CreateEventW(NULL, True, False, NULL) + if event == _winapi.NULL: + raise _winapi._WinError() + + if event: + self.overlapped[0].hEvent = event + else: + raise _winapi._WinError() + + if self.overlapped[0].hEvent == _ffi.NULL: + raise _winapi._WinError() + + def __del__(self): + bytes = _ffi.new("DWORD[1]",[0]) + olderr = _kernel32.GetLastError() + hascompletedio = HasOverlappedIoCompleted(self.overlapped[0]) + if not hascompletedio and self.type != OverlappedType.TYPE_NOT_STARTED: + + wait = _kernel32.CancelIoEx(self.handle, self.overlapped) + ret = self.GetOverlappedResult(wait) + err = _winapi.ERROR_SUCCESS + if not ret: + err = _kernel32.GetLastError() + self.error = err + if err != _winapi.ERROR_SUCCESS and \ + err != _winapi.ERROR_NOT_FOUND and \ + err != _winapi.ERROR_OPERATION_ABORTED: + SetFromWindowsErr(err) + if self.overlapped[0].hEvent != 0: + _winapi.CloseHandle(self.overlapped[0].hEvent) + + @property + def event(self): + return self.overlapped[0].hEvent + + def GetOverlappedResult(self, wait): + transferred = _ffi.new('DWORD[1]', [0]) + + if self.type == OverlappedType.TYPE_NONE: + return _ffi.NULL + + if self.type == OverlappedType.TYPE_NOT_STARTED: + return _ffi.NULL + + res = _kernel32.GetOverlappedResult(self.handle, self.overlapped, transferred, wait != 0) + if res: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + self.error = err + + if err != _winapi.ERROR_SUCCESS and err != _winapi.ERROR_MORE_DATA: + if not (err == _winapi.ERROR_BROKEN_PIPE and (self.type in [OverlappedType.TYPE_READ, OverlappedType.TYPE_READINTO])): + SetFromWindowsErr(err) + + if self.type == OverlappedType.TYPE_READ: + return _ffi.unpack(self.read_buffer, transferred[0]) + else: + return transferred[0] + + def getbuffer(self): + xxx + return None + + def cancel(self): + result = True + if self.type == OverlappedType.TYPE_NOT_STARTED or self.type == OverlappedType.TYPE_WAIT_NAMED_PIPE_AND_CONNECT: + return None + if not HasOverlappedIoCompleted(self.overlapped[0]): + ### If we are to support xp we will need to dynamically load the below method + result = _kernel32.CancelIoEx(self.handle, self.overlapped) + if (not result and _kernel32.GetLastError() != _winapi.ERROR_NOT_FOUND): + SetFromWindowsErr(0) + + def WSARecv(self ,handle, size, flags): + handle = _int2handle(handle) + flags = _int2dword(flags) + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + self.type = OverlappedType.TYPE_READ + self.handle = _int2handle(handle) + self.read_buffer = _ffi.new("CHAR[]", max(1,size)) + return self.do_WSARecv(handle, self.read_buffer, size, flags) + + def do_WSARecv(self, handle, allocatedbuffer, size, flags): + nread = _ffi.new("LPDWORD") + wsabuff = _ffi.new("WSABUF[1]") + buffercount = _ffi.new("DWORD[1]", [1]) + pflags = _ffi.new("LPDWORD") + pflags[0] = flags + + wsabuff[0].len = size + wsabuff[0].buf = allocatedbuffer + + result = _winsock2.WSARecv(handle, wsabuff, _int2dword(1), nread, pflags, self.overlapped, _ffi.NULL) + if result == SOCKET_ERROR: + self.error = _kernel32.GetLastError() + else: + self.error = _winapi.ERROR_SUCCESS + + if self.error == _winapi.ERROR_BROKEN_PIPE: + mark_as_completed(self.overlapped) + SetFromWindowsErr(self.error) + elif self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING] : + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def WSASend(self ,handle, bufobj, flags): + handle = _int2handle(handle) + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + self.write_buffer = bufobj + self.type = OverlappedType.TYPE_WRITE + self.handle = handle + + wsabuff = _ffi.new("WSABUF[1]") + wsabuff[0].len = len(bufobj) + wsabuff[0].buf = _ffi.new("CHAR[]", bufobj) + nwritten = _ffi.new("LPDWORD") + + result = _winsock2.WSASend(handle, wsabuff, _int2dword(1), nwritten, flags, self.overlapped, _ffi.NULL) + + if result == SOCKET_ERROR: + self.error = _kernel32.GetLastError() + else: + self.error = _winapi.ERROR_SUCCESS + + if self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_IO_PENDING]: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def getresult(self, wait=False): + return self.GetOverlappedResult(wait) + + def ConnectNamedPipe(self, handle): + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + self.type = OverlappedType.TYPE_CONNECT_NAMED_PIPE + self.handle = _int2handle(handle) + success = _kernel32.ConnectNamedPipe(self.handle, self.overlapped) + + if success: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + self.error = err + + if err == _winapi.ERROR_IO_PENDING | _winapi.ERROR_SUCCESS: + return False + elif err == _winapi.ERROR_PIPE_CONNECTED: + mark_as_completed(self.overlapped) + return True + else: + SetFromWindowsErr(err) + + def ReadFile(self, handle, size): + self.type = OverlappedType.TYPE_READ + self.handle = _int2handle(handle) + self.read_buffer = _ffi.new("CHAR[]", max(1,size)) + return self.do_ReadFile(self.handle, self.read_buffer, size) + + def do_ReadFile(self, handle, buf, size): + nread = _ffi.new('DWORD[1]', [0]) + ret = _kernel32.ReadFile(handle, buf, size, nread, self.overlapped) + if ret: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + + self.error = err + + if err == _winapi.ERROR_BROKEN_PIPE: + mark_as_completed(self.overlapped) + SetFromWindowsErr(err) + elif err in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING]: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(err) + + def WriteFile(self, handle, buffer): + self.handle = _int2handle(handle) + self.write_buffer = buffer + written = _ffi.new('DWORD[1]', [0]) + + # Check if we have already performed some IO + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + self.type = OverlappedType.TYPE_WRITE + + ret = _kernel32.WriteFile(self.handle, self.write_buffer, len(self.write_buffer), written, self.overlapped) + + if ret: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def AcceptEx(self, listensocket, acceptsocket): + listensocket = _int2handle(listensocket) + acceptsocket = _int2handle(acceptsocket) + bytesreceived = _ffi.new("DWORD[1]") + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + size = _ffi.sizeof("struct sockaddr_in6") + 16 + buf = _ffi.new("CHAR[]", size*2) + if not buf: + return None + + self.type = OverlappedType.TYPE_ACCEPT + self.handle = listensocket + self.read_buffer = buf + + res = _accept_ex[0](listensocket, acceptsocket, buf, \ + 0, size, size, bytesreceived, self.overlapped) + + if res: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(0) + + def DisconnectEx(self, socket, flags): + xxx + return None + + def ConnectEx(self, socket, addressobj): + socket = _int2handle(socket) + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + address = _ffi.new("struct sockaddr_in6*") + length = _ffi.sizeof("struct sockaddr_in6") + + address, length = parse_address(addressobj, _ffi.cast("SOCKADDR*",address), length) + + if length < 0: + return None + + self.type = OverlappedType.TYPE_CONNECT + self.handle = socket + + res = _connect_ex[0](socket, address, length, \ + _ffi.NULL, 0, _ffi.NULL, self.overlapped) + + if res: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(0) + + @property + def pending(self): + return (not HasOverlappedIoCompleted(self.overlapped[0]) and + self.type != OverlappedType.TYPE_NOT_STARTED) + + @property + def address(self): + return _handle2int(self.overlapped) + +def SetEvent(handle): + ret = _kernel32.SetEvent(_int2handle(handle)) + if not ret: + raise _winapi._WinError() + +def mark_as_completed(overlapped): + overlapped[0].Internal = 0 + if overlapped[0].hEvent != _ffi.NULL: + SetEvent(overlapped[0].hEvent) + +def CreateEvent(eventattributes, manualreset, initialstate, name): + event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name)) + event = _handle2int(event) + if not event: + raise _winapi._WinError() + return event + +def CreateIoCompletionPort(handle, existingcompletionport, completionkey, numberofconcurrentthreads): + completionkey = _int2intptr(completionkey) + existingcompletionport = _int2handle(existingcompletionport) + numberofconcurrentthreads = _int2dword(numberofconcurrentthreads) + handle = _int2handle(handle) + result = _kernel32.CreateIoCompletionPort(handle, + existingcompletionport, + completionkey, + numberofconcurrentthreads) + if result == _ffi.NULL: + raise SetFromWindowsErr(0) + return _handle2int(result) + +def PostQueuedCompletionStatus(completionport, ms): + raise _winapi._WinError() + +def GetQueuedCompletionStatus(completionport, milliseconds): + numberofbytes = _ffi.new('DWORD[1]', [0]) + completionkey = _ffi.new('ULONG**') + completionport = _int2handle(completionport) + + if completionport is None: + raise _winapi._WinError() + overlapped = _ffi.new("OVERLAPPED**") + overlapped[0] = _ffi.NULL + result = _kernel32.GetQueuedCompletionStatus(completionport, + numberofbytes, + completionkey, + overlapped, + milliseconds) + if result: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + + if overlapped[0] == _ffi.NULL: + if err == _winapi.WAIT_TIMEOUT: + return None + return SetFromWindowsErr(err) + + return (err, numberofbytes, _handle2int(completionkey[0]), _handle2int(_ffi.addressof(overlapped[0][0]))) + + at _ffi.callback("void(void*, int)") +def post_to_queue_callback(lpparameter, timerorwaitfired): + pdata = _ffi.cast("PostCallbackData*", lpparameter) + ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, timerorwaitfired, _ffi.cast("ULONG_PTR",0), pdata.Overlapped) + result = False + _winapi.free(pdata) + + +def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds): + data = _ffi.cast('PostCallbackData*', _winapi.malloc( _ffi.sizeof("PostCallbackData"))) + newwaitobject = _ffi.new("HANDLE*") + data[0].hCompletionPort = _int2handle(completionport) + data[0].Overlapped = _int2overlappedptr(ovaddress) + ret = _kernel32.RegisterWaitForSingleObject(newwaitobject, + _int2handle(object), + _ffi.cast("WAITORTIMERCALLBACK",post_to_queue_callback), + data, + miliseconds, + _kernel32.WT_EXECUTEINWAITTHREAD | _kernel32.WT_EXECUTEONLYONCE) + if not ret: + SetFromWindowsErr(0) + + return _handle2int(newwaitobject[0]) + +def ConnectPipe(address): + err = _winapi.ERROR_PIPE_BUSY + waddress = _ffi.new("wchar_t[]", address) + handle = _kernel32.CreateFileW(waddress, + _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, + 0, + _ffi.NULL, + _winapi.OPEN_EXISTING, + _winapi.FILE_FLAG_OVERLAPPED, + _ffi.NULL) + err = _kernel32.GetLastError() + + if handle == INVALID_HANDLE_VALUE or err == _winapi.ERROR_PIPE_BUSY: + SetFromWindowsErr(err) + + return _handle2int(handle) + +def UnregisterWaitEx(handle, event): + waithandle = _int2handle(handle) + waitevent = _int2handle(event) + + ret = _kernel32.UnregisterWaitEx(waithandle, waitevent) + + if not ret: + SetFromWindowsErr(0) + +def UnregisterWait(handle): + handle = _int2handle(handle) + + ret = _kernel32.UnregisterWait(handle) + + if not ret: + SetFromWindowsErr(0) + +def BindLocal(socket, family): + socket = _int2handle(socket) + if family == AF_INET: + addr = _ffi.new("struct sockaddr_in*") + addr[0].sin_family = AF_INET + addr[0].sin_port = 0 + addr[0].sin_addr.S_un.S_addr = INADDR_ANY + paddr = _ffi.cast("PSOCKADDR", addr) + result = _winsock2.bind(socket, paddr, _ffi.sizeof("struct sockaddr_in")) + elif family == AF_INET6: + addr = _ffi.new("struct sockaddr_in6*") + addr.sin6_family = AF_INET6 + addr.sin6_port = 0 + addr.sin6_addr = in6addr_any[0] + result = _winsock2.bind(socket, _ffi.cast("PSOCKADDR", addr), _ffi.sizeof("struct sockaddr_in")) + else: + raise ValueError() + + if result == SOCKET_ERROR: + SetFromWindowsErr(0) + +def HasOverlappedIoCompleted(overlapped): + return (overlapped.Internal != STATUS_PENDING) + +def parse_address(addressobj, address, length): + lengthptr = _ffi.new("INT*") + lengthptr[0] = length + if len(addressobj) == 2: + host,port = addressobj + address[0].sa_family = AF_INET + result = _winsock2.WSAStringToAddressW(host, AF_INET, _ffi.NULL, address, lengthptr) + if result < 0: + raise _winapi.WinError() + _ffi.cast("SOCKADDR_IN*",address)[0].sin_port = _winsock2.htons(port) + return address, lengthptr[0] + elif len(addressobj) == 4: + host, port, flowinfo, scopeid = addressobj + address.sa_family = AF_INET6 + result = _winsock2.WSAStringToAddressW(host, AF_INET6, _ffi.NULL, address, lengthptr) + address.sin6_port = _winsock2.htons(port) + address.sin6_flowinfo = flowinfo + address.sin6_scopeid = scopeid + return address, lengthptr[0] + else: + return -1 + + + + + + + diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -90,7 +90,6 @@ HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED; - DWORD WINAPI GetVersion(void); BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, void *, DWORD); HANDLE WINAPI CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD, @@ -101,16 +100,17 @@ DWORD, DWORD, HANDLE); HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD); BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED); HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR); HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR); -VOID WINAPI SetEvent(HANDLE); +BOOL WINAPI SetEvent(HANDLE); +BOOL WINAPI CancelIo(HANDLE); BOOL WINAPI CancelIoEx(HANDLE, LPOVERLAPPED); BOOL WINAPI CloseHandle(HANDLE); DWORD WINAPI GetLastError(VOID); BOOL WINAPI GetOverlappedResult(HANDLE, LPOVERLAPPED, LPDWORD, BOOL); - HANDLE WINAPI GetCurrentProcess(void); BOOL WINAPI DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD); @@ -121,19 +121,171 @@ void *, BOOL, DWORD, wchar_t *, wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION); DWORD WINAPI WaitForSingleObject(HANDLE, DWORD); +DWORD WaitForMultipleObjects(DWORD, HANDLE*, BOOL, DWORD); BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD); BOOL WINAPI TerminateProcess(HANDLE, UINT); HANDLE WINAPI GetStdHandle(DWORD); DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD); - UINT WINAPI SetErrorMode(UINT); #define SEM_FAILCRITICALERRORS 0x0001 #define SEM_NOGPFAULTERRORBOX 0x0002 #define SEM_NOALIGNMENTFAULTEXCEPT 0x0004 #define SEM_NOOPENFILEERRORBOX 0x8000 + +typedef struct _PostCallbackData { + HANDLE hCompletionPort; + LPOVERLAPPED Overlapped; +} PostCallbackData, *LPPostCallbackData; + +typedef VOID (WINAPI *WAITORTIMERCALLBACK) (PVOID, BOOL); +BOOL WINAPI RegisterWaitForSingleObject(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, ULONG, ULONG); + +BOOL WINAPI PostQueuedCompletionStatus(HANDLE, DWORD, ULONG_PTR, LPOVERLAPPED); +BOOL WINAPI UnregisterWaitEx(HANDLE, HANDLE); +BOOL WINAPI UnregisterWait(HANDLE); + +BOOL WINAPI GetQueuedCompletionStatus(HANDLE, LPDWORD, ULONG**, LPOVERLAPPED*, DWORD); +HANDLE WINAPI CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD); + +BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); + +#define WT_EXECUTEINWAITTHREAD 0x00000004 +#define WT_EXECUTEONLYONCE 0x00000008 + +HANDLE GetProcessHeap(); +LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T); +BOOL HeapFree(HANDLE, DWORD, LPVOID); + """) -# -------------------- +# -------------------- Win Sock 2 ---------------------- + +ffi.cdef(""" +typedef struct _WSABUF { + ULONG len; + CHAR *buf; +} WSABUF, *LPWSABUF; + +typedef HANDLE SOCKET; +SOCKET __stdcall socket(int, int, int); +int closesocket(SOCKET); + + +typedef BOOL (__stdcall * LPFN_DISCONNECTEX) (SOCKET, LPOVERLAPPED, DWORD, DWORD); +typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE) (DWORD, DWORD, LPVOID); + +int __stdcall WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); +int __stdcall WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); +int __stdcall WSAIoctl(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); + + +typedef struct _GUID { + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[8]; +} GUID; + +typedef USHORT ADDRESS_FAMILY; + +typedef struct in6_addr { + union { + UCHAR Byte[16]; + USHORT Word[8]; + } u; +} IN6_ADDR, *PIN6_ADDR, *LPIN6_ADDR; + +typedef struct { + union { + struct { + ULONG Zone : 28; + ULONG Level : 4; + }; + ULONG Value; + }; +} SCOPE_ID, *PSCOPE_ID; + +typedef struct sockaddr_in6 { + ADDRESS_FAMILY sin6_family; + USHORT sin6_port; + ULONG sin6_flowinfo; + IN6_ADDR sin6_addr; + union { + ULONG sin6_scope_id; + SCOPE_ID sin6_scope_struct; + }; +} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH; + +typedef struct in_addr { + union { + struct { + UCHAR s_b1; + UCHAR s_b2; + UCHAR s_b3; + UCHAR s_b4; + } S_un_b; + struct { + USHORT s_w1; + USHORT s_w2; + } S_un_w; + ULONG S_addr; + } S_un; +} INADDR, *PINADDR; + +typedef struct sockaddr_in { + SHORT sin_family; + USHORT sin_port; + INADDR sin_addr; + CHAR sin_zero[8]; +} SOCKADDR_IN, *PSOCKADDR_IN, *LPSOCKADDR_IN; + +typedef struct sockaddr { + USHORT sa_family; + CHAR sa_data[14]; +} SOCKADDR, *PSOCKADDR, *LPSOCKADDR; + +int bind(SOCKET, const PSOCKADDR, int); + +#define MAX_PROTOCOL_CHAIN 7 + +typedef struct _WSAPROTOCOLCHAIN { + int ChainLen; + DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; +} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN; + +#define WSAPROTOCOL_LEN 255 + +typedef struct _WSAPROTOCOL_INFOW { + DWORD dwServiceFlags1; + DWORD dwServiceFlags2; + DWORD dwServiceFlags3; + DWORD dwServiceFlags4; + DWORD dwProviderFlags; + GUID ProviderId; + DWORD dwCatalogEntryId; + WSAPROTOCOLCHAIN ProtocolChain; + int iVersion; + int iAddressFamily; + int iMaxSockAddr; + int iMinSockAddr; + int iSocketType; + int iProtocol; + int iProtocolMaxOffset; + int iNetworkByteOrder; + int iSecurityScheme; + DWORD dwMessageSize; + DWORD dwProviderReserved; + WCHAR szProtocol[WSAPROTOCOL_LEN + 1]; +} WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW; + +int __stdcall WSAStringToAddressW(LPWSTR, int, LPWSAPROTOCOL_INFOW, LPSOCKADDR, int* ); + +typedef BOOL (WINAPI* AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const PSOCKADDR, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *DisconnectExPtr)(SOCKET, LPOVERLAPPED, DWORD, DWORD); + +USHORT htons(USHORT); +""") if __name__ == "__main__": ffi.compile() diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py --- a/lib_pypy/_pypy_winbase_cffi.py +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -3,8 +3,8 @@ ffi = _cffi_backend.FFI('_pypy_winbase_cffi', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xAB\x03\x00\x00\x13\x11\x00\x00\xB0\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\xAA\x03\x00\x00\xA8\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\xA7\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x29\x11\x00\x00\x18\x03\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x6B\x03\x00\x00\x49\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x33\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x66\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\xA9\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xAB\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x6E\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6B\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x77\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\xB0\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x04\x09\x00\x00\x02\x09\x00\x00\x05\x09\x00\x00\x03\x09\x00\x00\x02\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\xAF\x03\x00\x00\x04\x01\x00\x00\x00\x01', - _globals = (b'\x00\x00\x27\x23CancelIoEx',0,b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x27\x23ConnectNamedPipe',0,b'\x00\x00\x6D\x23CreateEventA',0,b'\x00\x00\x73\x23CreateEventW',0,b'\x00\x00\x79\x23CreateFileA',0,b'\x00\x00\x9B\x23CreateFileW',0,b'\x00\x00\x82\x23CreateNamedPipeA',0,b'\x00\x00\x91\x23CreateNamedPipeW',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x48\x23CreateProcessW',0,b'\x00\x00\x3F\x23DuplicateHandle',0,b'\x00\x00\x8F\x23GetCurrentProcess',0,b'\x00\x00\x35\x23GetExitCodeProcess',0,b'\x00\x00\x63\x23GetLastError',0,b'\x00\x00\x5E\x23GetModuleFileNameW',0,b'\x00\x00\x2B\x23GetOverlappedResult',0,b'\x00\x00\x8C\x23GetStdHandle',0,b'\x00\x00\x63\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x57\x23SetErrorMode',0,b'\x00\x00\xA4\x23SetEvent',0,b'\x00\x00\x39\x23SetNamedPipeHandleState',0,b'\x00\x00\x31\x23TerminateProcess',0,b'\x00\x00\x5A\x23WaitForSingleObject',0,b'\x00\x00\x54\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x68\x23_getwch',0,b'\x00\x00\x68\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x6A\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x65\x23_ungetwch',0), - _struct_unions = ((b'\x00\x00\x00\xAD\x00\x00\x00\x03$1',b'\x00\x00\xAC\x11DUMMYSTRUCTNAME',b'\x00\x00\x15\x11Pointer'),(b'\x00\x00\x00\xAC\x00\x00\x00\x02$2',b'\x00\x00\x18\x11Offset',b'\x00\x00\x18\x11OffsetHigh'),(b'\x00\x00\x00\xA8\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\xAA\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x66\x11wShowWindow',b'\x00\x00\x66\x11cbReserved2',b'\x00\x00\xAE\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError'),(b'\x00\x00\x00\xA7\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x18\x11Internal',b'\x00\x00\x18\x11InternalHigh',b'\x00\x00\xAD\x11DUMMYUNIONNAME',b'\x00\x00\x15\x11hEvent'),(b'\x00\x00\x00\xA9\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x18\x11nLength',b'\x00\x00\x15\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle')), - _typenames = (b'\x00\x00\x00\x29LPOVERLAPPED',b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x6ELPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\xA7OVERLAPPED',b'\x00\x00\x00\xA8PROCESS_INFORMATION',b'\x00\x00\x00\x6EPSECURITY_ATTRIBUTES',b'\x00\x00\x00\xA9SECURITY_ATTRIBUTES',b'\x00\x00\x00\xAASTARTUPINFO',b'\x00\x00\x00\x66wint_t'), + _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x68\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x42\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x3B\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x4C\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x47\x03\x00\x01\x3C\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x32\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x48\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x2D\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x68\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xE2\x03\x00\x00\x07\x01\x00\x01\x4B\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xDD\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x41\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x4C\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEC\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xE2\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF5\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x68\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x68\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x38\x03\x00\x00\x13\x09\x00\x01\x3A\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x3E\x03\x00\x00\x0E\x09\x00\x01\x40\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x46\x03\x00\x01\x45\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x4A\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x4C\x05\x00\x00\x00\x0E\x00\x01\x4C\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\x98\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x5F\x03\x00\x00\x04\x01\x00\x01\x5F\x05\x00\x00\x00\x10\x00\x01\x5F\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xDD\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xE2\x05\x00\x00\x01\x00', + _globals = (b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xEB\x23CreateEventA',0,b'\x00\x00\xF1\x23CreateEventW',0,b'\x00\x00\xF7\x23CreateFileA',0,b'\x00\x01\x24\x23CreateFileW',0,b'\x00\x01\x12\x23CreateIoCompletionPort',0,b'\x00\x01\x00\x23CreateNamedPipeA',0,b'\x00\x01\x1A\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xB9\x23CreateProcessW',0,b'\x00\x00\xA2\x23DuplicateHandle',0,b'\x00\x01\x18\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xDA\x23GetLastError',0,b'\x00\x00\xD5\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xE9\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x0F\x23GetStdHandle',0,b'\x00\x00\xDA\x23GetVersion',0,b'\x00\x00\xE4\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC8\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xB2\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xCB\x23WaitForMultipleObjects',0,b'\x00\x00\xD1\x23WaitForSingleObject',0,b'\x00\x00\xAB\x23WriteFile',0,b'\x00\x00\xC5\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xDF\x23_getwch',0,b'\x00\x00\xDF\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE1\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xDC\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xDC\x23htons',0,b'\x00\x01\x0A\x23socket',0), + _struct_unions = ((b'\x00\x00\x01\x59\x00\x00\x00\x03$1',b'\x00\x01\x55\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x55\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x5A\x00\x00\x00\x03$3',b'\x00\x01\x60\x11Byte',b'\x00\x01\x66\x11Word'),(b'\x00\x00\x01\x5B\x00\x00\x00\x01$4',b'\x00\x01\x56\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x56\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x5C\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x40\x11sin6_scope_struct'),(b'\x00\x00\x01\x5D\x00\x00\x00\x03$7',b'\x00\x01\x57\x11S_un_b',b'\x00\x01\x58\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x57\x00\x00\x00\x02$8',b'\x00\x01\x5F\x11s_b1',b'\x00\x01\x5F\x11s_b2',b'\x00\x01\x5F\x11s_b3',b'\x00\x01\x5F\x11s_b4'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$9',b'\x00\x00\xDD\x11s_w1',b'\x00\x00\xDD\x11s_w2'),(b'\x00\x00\x01\x3C\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x40\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x5B\x11'),(b'\x00\x00\x01\x47\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xDD\x11wShowWindow',b'\x00\x00\xDD\x11cbReserved2',b'\x00\x01\x5E\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x36\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xDD\x11Data2',b'\x00\x00\xDD\x11Data3',b'\x00\x01\x62\x11Data4'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x59\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x41\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x64\x11ChainEntries'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x36\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x4A\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x69\x11szProtocol'),(b'\x00\x00\x01\x38\x00\x00\x00\x02in6_addr',b'\x00\x01\x5A\x11u'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02in_addr',b'\x00\x01\x5D\x11S_un'),(b'\x00\x00\x01\x42\x00\x00\x00\x02sockaddr',b'\x00\x00\xDD\x11sa_family',b'\x00\x01\x4D\x11sa_data'),(b'\x00\x00\x01\x46\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x54\x11sin_family',b'\x00\x00\xDD\x11sin_port',b'\x00\x01\x3A\x11sin_addr',b'\x00\x01\x4F\x11sin_zero'),(b'\x00\x00\x01\x45\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xDD\x11sin6_family',b'\x00\x00\xDD\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x38\x11sin6_addr',b'\x00\x01\x5C\x11')), + _typenames = (b'\x00\x00\x00\xDDADDRESS_FAMILY',b'\x00\x00\x01\x53AcceptExPtr',b'\x00\x00\x01\x52ConnectExPtr',b'\x00\x00\x01\x51DisconnectExPtr',b'\x00\x00\x01\x36GUID',b'\x00\x00\x01\x38IN6_ADDR',b'\x00\x00\x01\x3AINADDR',b'\x00\x00\x01\x51LPFN_DISCONNECTEX',b'\x00\x00\x01\x37LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x3DLPPostCallbackData',b'\x00\x00\x00\xECLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x43LPSOCKADDR_IN',b'\x00\x00\x01\x44LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x49LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB5LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x3BOVERLAPPED',b'\x00\x00\x01\x37PIN6_ADDR',b'\x00\x00\x01\x39PINADDR',b'\x00\x00\x01\x3CPROCESS_INFORMATION',b'\x00\x00\x01\x3FPSCOPE_ID',b'\x00\x00\x00\xECPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x43PSOCKADDR_IN',b'\x00\x00\x01\x44PSOCKADDR_IN6_LH',b'\x00\x00\x01\x3EPostCallbackData',b'\x00\x00\x01\x40SCOPE_ID',b'\x00\x00\x01\x41SECURITY_ATTRIBUTES',b'\x00\x00\x01\x42SOCKADDR',b'\x00\x00\x01\x46SOCKADDR_IN',b'\x00\x00\x01\x45SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x47STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x48WSABUF',b'\x00\x00\x01\x4AWSAPROTOCOLCHAIN',b'\x00\x00\x01\x4BWSAPROTOCOL_INFOW',b'\x00\x00\x00\xDDwint_t'), ) diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -17,10 +17,25 @@ NULL = _ffi.NULL # Now the _subprocess module implementation +def _WinError(type=WindowsError): + code, message = _ffi.getwinerror() + excep = type(None, message, None ,code) + raise excep -def _WinError(): - code, message = _ffi.getwinerror() - raise WindowsError(code, message) +# In CPython this function converts a windows error into a python object +# Not sure what we should do here. +def SetFromWindowsErr(err): + if err == 0: + err = _kernel32.GetLastError() + + if err == ERROR_CONNECTION_REFUSED: + type = ConnectionRefusedError + elif err == ERROR_CONNECTION_ABORTED: + type = ConnectionAbortedError + else: + type = WindowsError + + return _WinError(type) def _int2handle(val): return _ffi.cast("HANDLE", val) @@ -32,25 +47,25 @@ def CreatePipe(attributes, size): handles = _ffi.new("HANDLE[2]") - + res = _kernel32.CreatePipe(handles, handles + 1, NULL, size) if not res: - raise _WinError() + SetFromWindowsErr(0) return _handle2int(handles[0]), _handle2int(handles[1]) def CreateNamedPipe(*args): handle = _kernel32.CreateNamedPipeW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() - return handle + SetFromWindowsErr(0) + return _handle2int(handle) def CreateFile(*args): handle = _kernel32.CreateFileW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() - return handle + SetFromWindowsErr(0) + return _handle2int(handle) def SetNamedPipeHandleState(namedpipe, mode, max_collection_count, collect_data_timeout): d0 = _ffi.new('DWORD[1]', [mode]) @@ -79,20 +94,20 @@ def __del__(self): # do this somehow else - xxx err = _kernel32.GetLastError() bytes = _ffi.new('DWORD[1]') - o = overlapped[0] - if overlapped[0].pending: + o = self.overlapped[0] + if self.pending: if _kernel32.CancelIoEx(o.handle, o.overlapped) & \ self.GetOverlappedResult(o.handle, o.overlapped, _ffi.addressof(bytes), True): # The operation is no longer pending, nothing to do pass else: - raise RuntimeError('deleting an overlapped strucwith a pending operation not supported') + raise RuntimeError('deleting an overlapped struct with a pending operation not supported') @property def event(self): + xxx return None def GetOverlappedResult(self, wait): @@ -110,8 +125,8 @@ else: self.pending = 0 raise _WinError() - if self.completed and self.read_buffer: - if transferred != len(self.read_buffer): + if self.completed and self.readbuffer: + if transferred != len(self.readbuffer): raise _WinError() return transferred[0], err @@ -125,6 +140,7 @@ def ConnectNamedPipe(handle, overlapped=False): + handle = _int2handle(handle) if overlapped: ov = Overlapped(handle) else: @@ -140,10 +156,10 @@ _kernel32.SetEvent(ov.overlapped[0].hEvent) else: del ov - raise _WinError() + SetFromWindowsErr(err) return ov elif not success: - raise _WinError() + SetFromWindowsErr(0) def GetCurrentProcess(): return _handle2int(_kernel32.GetCurrentProcess()) @@ -217,6 +233,18 @@ return res +def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds): + if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS: + return None + + # CPython makes the wait interruptible by ctrl-c. We need to add this in at some point + res = _kernel32.WaitForMultipleObjects(len(handle_sequence), handle_sequence, waitflag, milliseconds) + + if res == WAIT_FAILED: + raise _WinError() + return int(res) + + def GetExitCodeProcess(handle): # CPython: the first argument is expected to be an integer. code = _ffi.new("DWORD[1]") @@ -260,6 +288,14 @@ raise _WinError() return _ffi.string(buf) +ZERO_MEMORY = 0x00000008 + +def malloc(size): + return _kernel32.HeapAlloc(_kernel32.GetProcessHeap(),ZERO_MEMORY,size) + +def free(voidptr): + _kernel32.HeapFree(_kernel32.GetProcessHeap(),0, voidptr) + # #define macros from WinBase.h and elsewhere STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 @@ -272,6 +308,7 @@ WAIT_OBJECT_0 = 0 WAIT_ABANDONED_0 = 0x80 WAIT_TIMEOUT = 0x102 +WAIT_FAILED = 0xFFFFFFFF CREATE_NEW_CONSOLE = 0x010 CREATE_NEW_PROCESS_GROUP = 0x200 CREATE_UNICODE_ENVIRONMENT = 0x400 @@ -281,11 +318,14 @@ ERROR_SUCCESS = 0 ERROR_NETNAME_DELETED = 64 ERROR_BROKEN_PIPE = 109 +ERROR_PIPE_BUSY = 231 ERROR_MORE_DATA = 234 ERROR_PIPE_CONNECTED = 535 ERROR_OPERATION_ABORTED = 995 ERROR_IO_INCOMPLETE = 996 ERROR_IO_PENDING = 997 +ERROR_CONNECTION_REFUSED = 1225 +ERROR_CONNECTION_ABORTED = 1236 PIPE_ACCESS_INBOUND = 0x00000001 PIPE_ACCESS_OUTBOUND = 0x00000002 @@ -299,11 +339,13 @@ PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000 PIPE_REJECT_REMOTE_CLIENTS = 0x00000008 +PIPE_UNLIMITED_INSTANCES = 255 + GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 GENERIC_EXECUTE= 0x20000000 GENERIC_ALL = 0x10000000 -INVALID_HANDLE_VALUE = -1 +INVALID_HANDLE_VALUE = _int2handle(-1) FILE_FLAG_WRITE_THROUGH = 0x80000000 FILE_FLAG_OVERLAPPED = 0x40000000 FILE_FLAG_NO_BUFFERING = 0x20000000 @@ -326,3 +368,5 @@ OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 +MAXIMUM_WAIT_OBJECTS = 64 + diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -8,3 +8,8 @@ .. branch: zlib-make-py3-go-boom Complain if you try to copy a flushed zlib decompress on py3 + +.. branch: winoverlapped + +Add support for async (overlapped) IO on Windows. + From pypy.commits at gmail.com Sun Apr 14 03:55:18 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 00:55:18 -0700 (PDT) Subject: [pypy-commit] pypy issue2996: make second new test fail too Message-ID: <5cb2e766.1c69fb81.6fde6.cdb7@mx.google.com> Author: Matti Picus Branch: issue2996 Changeset: r96474:dd163eb782ad Date: 2019-04-14 10:54 +0300 http://bitbucket.org/pypy/pypy/changeset/dd163eb782ad/ Log: make second new test fail too diff --git a/pypy/objspace/std/test/test_callmethod.py b/pypy/objspace/std/test/test_callmethod.py --- a/pypy/objspace/std/test/test_callmethod.py +++ b/pypy/objspace/std/test/test_callmethod.py @@ -37,9 +37,9 @@ class Foo: def meth(*args, a=2, b=3): return args, a, b - ret = Foo().meth(**{}) + ret = Foo().meth(**{'a':4}) assert type(ret[0][0]) is Foo - assert ret[1] == 2 + assert ret[1] == 4 assert ret[2] == 3 """) From pypy.commits at gmail.com Sun Apr 14 06:15:56 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 03:15:56 -0700 (PDT) Subject: [pypy-commit] pypy default: document _overlapped in the release Message-ID: <5cb3085c.1c69fb81.8c081.bf22@mx.google.com> Author: Matti Picus Branch: Changeset: r96475:b694a5048039 Date: 2019-04-14 13:10 +0300 http://bitbucket.org/pypy/pypy/changeset/b694a5048039/ Log: document _overlapped in the release diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -90,6 +90,7 @@ * ``str.maketrans`` was broken (issue 2991_) * Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` and ``'a' < buffer`` +* Support ``_overlapped`` and asyncio on win32 .. _2984: https://bitbucket.org/pypy/pypy/issues/2984 .. _2991: https://bitbucket.org/pypy/pypy/issues/2991 From pypy.commits at gmail.com Sun Apr 14 06:15:58 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 03:15:58 -0700 (PDT) Subject: [pypy-commit] pypy default: update contributors Message-ID: <5cb3085e.1c69fb81.d3eac.024b@mx.google.com> Author: Matti Picus Branch: Changeset: r96476:92546e4e1bd5 Date: 2019-04-14 13:15 +0300 http://bitbucket.org/pypy/pypy/changeset/92546e4e1bd5/ Log: update contributors diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -110,6 +110,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -125,7 +126,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -254,6 +254,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -403,6 +404,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -77,6 +77,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -92,7 +93,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -221,6 +221,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -370,6 +371,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather From pypy.commits at gmail.com Sun Apr 14 06:22:24 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 03:22:24 -0700 (PDT) Subject: [pypy-commit] pypy release-pypy2.7-v7.x: merge default into release Message-ID: <5cb309e0.1c69fb81.66d48.35bf@mx.google.com> Author: Matti Picus Branch: release-pypy2.7-v7.x Changeset: r96477:8cdda8b8cdb8 Date: 2019-04-14 13:16 +0300 http://bitbucket.org/pypy/pypy/changeset/8cdda8b8cdb8/ Log: merge default into release diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -110,6 +110,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -125,7 +126,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -254,6 +254,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -403,6 +404,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.12.2 +Version: 1.12.3 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.2" -__version_info__ = (1, 12, 2) +__version__ = "1.12.3" +__version_info__ = (1, 12, 3) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -223,7 +223,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.2" + "\ncompiled with cffi version: 1.12.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -77,6 +77,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -92,7 +93,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -221,6 +221,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -370,6 +371,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v7.1.1.rst @@ -0,0 +1,98 @@ +========================================= +PyPy v7.1.1: release of 2.7, and 3.6-beta +========================================= + +The PyPy team is proud to release a bug-fix release version 7.1.1 of PyPy, which +includes two different interpreters: + + - PyPy2.7, which is an interpreter supporting the syntax and the features of + Python 2.7 + + - PyPy3.6-beta: this is the second official release of PyPy to support 3.6 + features, although it is still considered beta quality. + +The interpreters are based on much the same codebase, thus the double +release. + +As always, this release is 100% compatible with the previous one and fixed +several issues and bugs raised by the growing community of PyPy users. +We strongly recommend updating. + +The PyPy3.6 release is still not production quality so your mileage may vary. +There are open issues with incomplete compatibility and c-extension support. + +You can download the v7.1.1 releases here: + + http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project. If PyPy is not quite good enough for your needs, we are available for +direct consulting work. + +We would also like to thank our contributors and encourage new people to join +the project. PyPy has many layers and we need help with all of them: `PyPy`_ +and `RPython`_ documentation improvements, tweaking popular modules to run +on pypy, or general `help`_ with making RPython's JIT even better. + +.. _`PyPy`: index.html +.. _`RPython`: https://rpython.readthedocs.org +.. _`help`: project-ideas.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7, 3.6. It's fast (`PyPy and CPython 2.7.x`_ performance +comparison) due to its integrated tracing JIT compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +This PyPy release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +Unfortunately at the moment of writing our ARM buildbots are out of service, +so for now we are **not** releasing any binary for the ARM architecture, +although PyPy does support ARM 32 bit processors. + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + + +Changelog +========= + +Changes shared across versions +* improve performance of ``u''.append`` +* Prevent a crash in ``zlib`` when flushing a closed stream +* Fix a few corener cases when encountering unicode values above 0x110000 +* Teach the JIT how to handle very large constant lists, sets, or dicts +* Fix building on ARM32 (issue 2984_) +* Fix a bug in register assignment in ARM32 +* Package windows DLLs needed by cffi modules next to the cffi c-extensions + (issue 2988_) +* Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem`` +* Fix memoryviews of ctype structures with padding, (cpython issue 32780_) +* CFFI updated to as-yet-unreleased 1.12.3 + +Python 3.6 only + +* On win32, override some ``errno.E*`` values that were added to MSVC in v2010 + so that ``errno.E* == errno.WSAE*`` as in CPython +* Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the + AST level) +* ``str.maketrans`` was broken (issue 2991_) +* Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` + and ``'a' < buffer`` +* Support ``_overlapped`` and asyncio on win32 + +.. _2984: https://bitbucket.org/pypy/pypy/issues/2984 +.. _2991: https://bitbucket.org/pypy/pypy/issues/2991 +.. _2988: https://bitbucket.org/pypy/pypy/issues/2988 +.. _32780: https://bugs.python.org/issue32780 diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi from rpython.rtyper.lltypesystem import rffi -VERSION = "1.12.2" +VERSION = "1.12.3" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -1053,21 +1053,17 @@ code = r_uint(ord(item)) # cpython will allow values > sys.maxunicode # while silently truncating the top bits - if code <= r_uint(0x7F): - # Encode ASCII - item = chr(code) - elif code <= r_uint(0x07FF): - item = (chr((0xc0 | (code >> 6))) + - chr((0x80 | (code & 0x3f)))) - elif code <= r_uint(0xFFFF): - item = (chr((0xe0 | (code >> 12))) + - chr((0x80 | ((code >> 6) & 0x3f))) + - chr((0x80 | (code & 0x3f)))) - else: - item = (chr((0xf0 | (code >> 18)) & 0xff) + - chr((0x80 | ((code >> 12) & 0x3f))) + - chr((0x80 | ((code >> 6) & 0x3f))) + - chr((0x80 | (code & 0x3f)))) + # For now I (arigo) am going to ignore that and + # raise a ValueError always here, instead of getting + # some invalid utf8-encoded string which makes things + # potentially explode left and right. + try: + item = rutf8.unichr_as_utf8(code) + except rutf8.OutOfRange: + raise oefmt(space.w_ValueError, + "cannot operate on this array('u') because it contains" + " character %s not in range [U+0000; U+10ffff]" + " at index %d", 'U+%x' % code, idx) return space.newutf8(item, 1) assert 0, "unreachable" diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -851,7 +851,13 @@ a = self.array('u', input_unicode) b = self.array('u', input_unicode) b.byteswap() - assert a != b + assert b[2] == u'\u0000' + raises(ValueError, "b[1]") # doesn't work + e = raises(ValueError, "a != b") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") assert str(a) == "array('u', %r)" % (input_unicode,) assert str(b) == ("array('u', )") diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -42,13 +42,10 @@ self._length = length self._index_storage = rutf8.null_storage() if not we_are_translated(): - try: - # best effort, too expensive to handle surrogates - ulength = rutf8.codepoints_in_utf(utf8str) - except: - ulength = length - assert ulength == length - + # utf8str must always be a valid utf8 string, except maybe with + # explicit surrogate characters---which .decode('utf-8') doesn't + # special-case in Python 2, which is exactly what we want here + assert length == len(utf8str.decode('utf-8')) @staticmethod From pypy.commits at gmail.com Sun Apr 14 06:22:29 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 03:22:29 -0700 (PDT) Subject: [pypy-commit] pypy default: add 2997 fix to release note Message-ID: <5cb309e5.1c69fb81.80d2a.fc84@mx.google.com> Author: Matti Picus Branch: Changeset: r96479:caa1292bce3e Date: 2019-04-14 13:21 +0300 http://bitbucket.org/pypy/pypy/changeset/caa1292bce3e/ Log: add 2997 fix to release note diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -91,8 +91,11 @@ * Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` and ``'a' < buffer`` * Support ``_overlapped`` and asyncio on win32 +* Fix an issue where ``''.join(list_of_strings)`` would rarely confuse utf8 and + bytes (issue 2997_) .. _2984: https://bitbucket.org/pypy/pypy/issues/2984 .. _2991: https://bitbucket.org/pypy/pypy/issues/2991 .. _2988: https://bitbucket.org/pypy/pypy/issues/2988 +.. _2997: https://bitbucket.org/pypy/pypy/issues/2997 .. _32780: https://bugs.python.org/issue32780 From pypy.commits at gmail.com Sun Apr 14 06:22:26 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 03:22:26 -0700 (PDT) Subject: [pypy-commit] pypy release-pypy3.6-v7.x: merge py3.6 into release Message-ID: <5cb309e2.1c69fb81.8623b.d393@mx.google.com> Author: Matti Picus Branch: release-pypy3.6-v7.x Changeset: r96478:784b254d6699 Date: 2019-04-14 13:17 +0300 http://bitbucket.org/pypy/pypy/changeset/784b254d6699/ Log: merge py3.6 into release diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_overlapped.py @@ -0,0 +1,612 @@ +""" +Support routines for overlapping io. +Currently, this extension module is only required when using the +modules on Windows. +""" + +import sys +if sys.platform != 'win32': + raise ImportError("The '_overlapped' module is only available on Windows") + +# Declare external Win32 functions + +from _pypy_winbase_cffi import ffi as _ffi +_kernel32 = _ffi.dlopen('kernel32') + +_winsock2 = _ffi.dlopen('Ws2_32') + +_mswsock = _ffi.dlopen('Mswsock') + +GetVersion = _kernel32.GetVersion +NULL = _ffi.NULL + +from _winapi import INVALID_HANDLE_VALUE, _MAX_PATH , _Z, SetFromWindowsErr +import _winapi + +# +# Error Codes +# +ERROR_IO_PENDING = 997 +ERROR_PIPE_BUSY = 231 +ERROR_NETNAME_DELETED = 64 + +SOCKET_ERROR = -1 + +AF_INET = 2 +AF_INET6 = 23 + +SOCK_STREAM = 1 +IPPROTO_TCP = 6 + +INVALID_SOCKET = -1 + +IOC_OUT = 0x40000000 +IOC_IN = 0x80000000 +IOC_INOUT = IOC_IN | IOC_OUT +IOC_WS2 = 0x08000000 + +def _WSAIORW(x, y): + return IOC_INOUT | x | y + +WSAID_ACCEPTEX = _ffi.new("GUID[1]") +WSAID_ACCEPTEX[0].Data1 = 0xb5367df1 +WSAID_ACCEPTEX[0].Data2 = 0xcbac +WSAID_ACCEPTEX[0].Data3 = 0x11cf +WSAID_ACCEPTEX[0].Data4 = [0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92] + + +WSAID_CONNECTEX = _ffi.new("GUID[1]") +WSAID_CONNECTEX[0].Data1 = 0x25a207b9 +WSAID_CONNECTEX[0].Data2 = 0xddf3 +WSAID_CONNECTEX[0].Data3 = 0x4660 +WSAID_CONNECTEX[0].Data4 = [0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e] + +WSAID_DISCONNECTEX = _ffi.new("GUID[1]") +WSAID_DISCONNECTEX[0].Data1 = 0x7fda2e11 +WSAID_DISCONNECTEX[0].Data2 = 0x8630 +WSAID_DISCONNECTEX[0].Data3 = 0x436f +WSAID_DISCONNECTEX[0].Data4 = [0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57] + +SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6) + +SO_UPDATE_ACCEPT_CONTEXT = 0x700B +SO_UPDATE_CONNECT_CONTEXT = 0x7010 +INADDR_ANY = 0x00000000 +in6addr_any = _ffi.new("struct in6_addr[1]") + +# Status Codes +STATUS_PENDING = 0x00000103 + + +def _int2intptr(int2cast): + return _ffi.cast("ULONG_PTR", int2cast) + +def _int2dword(int2cast): + return _ffi.cast("DWORD", int2cast) + +def _int2handle(val): + return _ffi.cast("HANDLE", val) + +def _int2overlappedptr(val): + return _ffi.cast("OVERLAPPED*", val) + +def _handle2int(handle): + return int(_ffi.cast("intptr_t", handle)) + +from enum import Enum +class OverlappedType(Enum): + TYPE_NONE = 0 + TYPE_NOT_STARTED = 1 + TYPE_READ = 2 + TYPE_READINTO = 3 + TYPE_WRITE = 4 + TYPE_ACCEPT = 5 + TYPE_CONNECT = 6 + TYPE_DISCONNECT = 7 + TYPE_CONNECT_NAMED_PIPE = 8 + TYPE_WAIT_NAMED_PIPE_AND_CONNECT = 9 + TYPE_TRANSMIT_FILE = 10 + +_accept_ex = _ffi.new("AcceptExPtr*") +_connect_ex = _ffi.new("ConnectExPtr*") +_disconnect_ex = _ffi.new("DisconnectExPtr*") + + +def initiailize_function_ptrs(): + ## importing socket ensures that WSAStartup() is called + import _socket + s = _winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + dwBytes = _ffi.new("DWORD[1]", [0]) + if s == INVALID_SOCKET: + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_ACCEPTEX, _ffi.sizeof(WSAID_ACCEPTEX[0]), _accept_ex, \ + _ffi.sizeof(_accept_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + if result == INVALID_SOCKET: + _winsock2.closesocket(s) + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_CONNECTEX, _ffi.sizeof(WSAID_CONNECTEX[0]), _connect_ex, \ + _ffi.sizeof(_connect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + if result == INVALID_SOCKET: + _winsock2.closesocket(s) + raise _winapi._WinError() + + result = _winsock2.WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + WSAID_DISCONNECTEX, _ffi.sizeof(WSAID_DISCONNECTEX[0]), _disconnect_ex, \ + _ffi.sizeof(_disconnect_ex[0]), dwBytes, _ffi.NULL, _ffi.NULL) + + _winsock2.closesocket(s) + if result == INVALID_SOCKET: + raise _winapi._WinError() + + +initiailize_function_ptrs() + + +class Overlapped(object): + def __init__(self, event=_ffi.NULL): + self.overlapped = _ffi.new('OVERLAPPED[1]') + self.handle = _ffi.NULL + self.read_buffer = None + self.write_buffer = None + self.error = 0 + + self.type = OverlappedType.TYPE_NONE + if event == _int2handle(INVALID_HANDLE_VALUE) or not event: + event = _kernel32.CreateEventW(NULL, True, False, NULL) + if event == _winapi.NULL: + raise _winapi._WinError() + + if event: + self.overlapped[0].hEvent = event + else: + raise _winapi._WinError() + + if self.overlapped[0].hEvent == _ffi.NULL: + raise _winapi._WinError() + + def __del__(self): + bytes = _ffi.new("DWORD[1]",[0]) + olderr = _kernel32.GetLastError() + hascompletedio = HasOverlappedIoCompleted(self.overlapped[0]) + if not hascompletedio and self.type != OverlappedType.TYPE_NOT_STARTED: + + wait = _kernel32.CancelIoEx(self.handle, self.overlapped) + ret = self.GetOverlappedResult(wait) + err = _winapi.ERROR_SUCCESS + if not ret: + err = _kernel32.GetLastError() + self.error = err + if err != _winapi.ERROR_SUCCESS and \ + err != _winapi.ERROR_NOT_FOUND and \ + err != _winapi.ERROR_OPERATION_ABORTED: + SetFromWindowsErr(err) + if self.overlapped[0].hEvent != 0: + _winapi.CloseHandle(self.overlapped[0].hEvent) + + @property + def event(self): + return self.overlapped[0].hEvent + + def GetOverlappedResult(self, wait): + transferred = _ffi.new('DWORD[1]', [0]) + + if self.type == OverlappedType.TYPE_NONE: + return _ffi.NULL + + if self.type == OverlappedType.TYPE_NOT_STARTED: + return _ffi.NULL + + res = _kernel32.GetOverlappedResult(self.handle, self.overlapped, transferred, wait != 0) + if res: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + self.error = err + + if err != _winapi.ERROR_SUCCESS and err != _winapi.ERROR_MORE_DATA: + if not (err == _winapi.ERROR_BROKEN_PIPE and (self.type in [OverlappedType.TYPE_READ, OverlappedType.TYPE_READINTO])): + SetFromWindowsErr(err) + + if self.type == OverlappedType.TYPE_READ: + return _ffi.unpack(self.read_buffer, transferred[0]) + else: + return transferred[0] + + def getbuffer(self): + xxx + return None + + def cancel(self): + result = True + if self.type == OverlappedType.TYPE_NOT_STARTED or self.type == OverlappedType.TYPE_WAIT_NAMED_PIPE_AND_CONNECT: + return None + if not HasOverlappedIoCompleted(self.overlapped[0]): + ### If we are to support xp we will need to dynamically load the below method + result = _kernel32.CancelIoEx(self.handle, self.overlapped) + if (not result and _kernel32.GetLastError() != _winapi.ERROR_NOT_FOUND): + SetFromWindowsErr(0) + + def WSARecv(self ,handle, size, flags): + handle = _int2handle(handle) + flags = _int2dword(flags) + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + self.type = OverlappedType.TYPE_READ + self.handle = _int2handle(handle) + self.read_buffer = _ffi.new("CHAR[]", max(1,size)) + return self.do_WSARecv(handle, self.read_buffer, size, flags) + + def do_WSARecv(self, handle, allocatedbuffer, size, flags): + nread = _ffi.new("LPDWORD") + wsabuff = _ffi.new("WSABUF[1]") + buffercount = _ffi.new("DWORD[1]", [1]) + pflags = _ffi.new("LPDWORD") + pflags[0] = flags + + wsabuff[0].len = size + wsabuff[0].buf = allocatedbuffer + + result = _winsock2.WSARecv(handle, wsabuff, _int2dword(1), nread, pflags, self.overlapped, _ffi.NULL) + if result == SOCKET_ERROR: + self.error = _kernel32.GetLastError() + else: + self.error = _winapi.ERROR_SUCCESS + + if self.error == _winapi.ERROR_BROKEN_PIPE: + mark_as_completed(self.overlapped) + SetFromWindowsErr(self.error) + elif self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING] : + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def WSASend(self ,handle, bufobj, flags): + handle = _int2handle(handle) + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + self.write_buffer = bufobj + self.type = OverlappedType.TYPE_WRITE + self.handle = handle + + wsabuff = _ffi.new("WSABUF[1]") + wsabuff[0].len = len(bufobj) + wsabuff[0].buf = _ffi.new("CHAR[]", bufobj) + nwritten = _ffi.new("LPDWORD") + + result = _winsock2.WSASend(handle, wsabuff, _int2dword(1), nwritten, flags, self.overlapped, _ffi.NULL) + + if result == SOCKET_ERROR: + self.error = _kernel32.GetLastError() + else: + self.error = _winapi.ERROR_SUCCESS + + if self.error in [_winapi.ERROR_SUCCESS, _winapi.ERROR_IO_PENDING]: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def getresult(self, wait=False): + return self.GetOverlappedResult(wait) + + def ConnectNamedPipe(self, handle): + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + self.type = OverlappedType.TYPE_CONNECT_NAMED_PIPE + self.handle = _int2handle(handle) + success = _kernel32.ConnectNamedPipe(self.handle, self.overlapped) + + if success: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + self.error = err + + if err == _winapi.ERROR_IO_PENDING | _winapi.ERROR_SUCCESS: + return False + elif err == _winapi.ERROR_PIPE_CONNECTED: + mark_as_completed(self.overlapped) + return True + else: + SetFromWindowsErr(err) + + def ReadFile(self, handle, size): + self.type = OverlappedType.TYPE_READ + self.handle = _int2handle(handle) + self.read_buffer = _ffi.new("CHAR[]", max(1,size)) + return self.do_ReadFile(self.handle, self.read_buffer, size) + + def do_ReadFile(self, handle, buf, size): + nread = _ffi.new('DWORD[1]', [0]) + ret = _kernel32.ReadFile(handle, buf, size, nread, self.overlapped) + if ret: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + + self.error = err + + if err == _winapi.ERROR_BROKEN_PIPE: + mark_as_completed(self.overlapped) + SetFromWindowsErr(err) + elif err in [_winapi.ERROR_SUCCESS, _winapi.ERROR_MORE_DATA, _winapi.ERROR_IO_PENDING]: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(err) + + def WriteFile(self, handle, buffer): + self.handle = _int2handle(handle) + self.write_buffer = buffer + written = _ffi.new('DWORD[1]', [0]) + + # Check if we have already performed some IO + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + self.type = OverlappedType.TYPE_WRITE + + ret = _kernel32.WriteFile(self.handle, self.write_buffer, len(self.write_buffer), written, self.overlapped) + + if ret: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(self.error) + + def AcceptEx(self, listensocket, acceptsocket): + listensocket = _int2handle(listensocket) + acceptsocket = _int2handle(acceptsocket) + bytesreceived = _ffi.new("DWORD[1]") + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + size = _ffi.sizeof("struct sockaddr_in6") + 16 + buf = _ffi.new("CHAR[]", size*2) + if not buf: + return None + + self.type = OverlappedType.TYPE_ACCEPT + self.handle = listensocket + self.read_buffer = buf + + res = _accept_ex[0](listensocket, acceptsocket, buf, \ + 0, size, size, bytesreceived, self.overlapped) + + if res: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(0) + + def DisconnectEx(self, socket, flags): + xxx + return None + + def ConnectEx(self, socket, addressobj): + socket = _int2handle(socket) + + if self.type != OverlappedType.TYPE_NONE: + raise _winapi._WinError() + + address = _ffi.new("struct sockaddr_in6*") + length = _ffi.sizeof("struct sockaddr_in6") + + address, length = parse_address(addressobj, _ffi.cast("SOCKADDR*",address), length) + + if length < 0: + return None + + self.type = OverlappedType.TYPE_CONNECT + self.handle = socket + + res = _connect_ex[0](socket, address, length, \ + _ffi.NULL, 0, _ffi.NULL, self.overlapped) + + if res: + self.error = _winapi.ERROR_SUCCESS + else: + self.error = _kernel32.GetLastError() + + if self.error == _winapi.ERROR_SUCCESS or self.error == _winapi.ERROR_IO_PENDING: + return None + else: + self.type = OverlappedType.TYPE_NOT_STARTED + SetFromWindowsErr(0) + + @property + def pending(self): + return (not HasOverlappedIoCompleted(self.overlapped[0]) and + self.type != OverlappedType.TYPE_NOT_STARTED) + + @property + def address(self): + return _handle2int(self.overlapped) + +def SetEvent(handle): + ret = _kernel32.SetEvent(_int2handle(handle)) + if not ret: + raise _winapi._WinError() + +def mark_as_completed(overlapped): + overlapped[0].Internal = 0 + if overlapped[0].hEvent != _ffi.NULL: + SetEvent(overlapped[0].hEvent) + +def CreateEvent(eventattributes, manualreset, initialstate, name): + event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name)) + event = _handle2int(event) + if not event: + raise _winapi._WinError() + return event + +def CreateIoCompletionPort(handle, existingcompletionport, completionkey, numberofconcurrentthreads): + completionkey = _int2intptr(completionkey) + existingcompletionport = _int2handle(existingcompletionport) + numberofconcurrentthreads = _int2dword(numberofconcurrentthreads) + handle = _int2handle(handle) + result = _kernel32.CreateIoCompletionPort(handle, + existingcompletionport, + completionkey, + numberofconcurrentthreads) + if result == _ffi.NULL: + raise SetFromWindowsErr(0) + return _handle2int(result) + +def PostQueuedCompletionStatus(completionport, ms): + raise _winapi._WinError() + +def GetQueuedCompletionStatus(completionport, milliseconds): + numberofbytes = _ffi.new('DWORD[1]', [0]) + completionkey = _ffi.new('ULONG**') + completionport = _int2handle(completionport) + + if completionport is None: + raise _winapi._WinError() + overlapped = _ffi.new("OVERLAPPED**") + overlapped[0] = _ffi.NULL + result = _kernel32.GetQueuedCompletionStatus(completionport, + numberofbytes, + completionkey, + overlapped, + milliseconds) + if result: + err = _winapi.ERROR_SUCCESS + else: + err = _kernel32.GetLastError() + + if overlapped[0] == _ffi.NULL: + if err == _winapi.WAIT_TIMEOUT: + return None + return SetFromWindowsErr(err) + + return (err, numberofbytes, _handle2int(completionkey[0]), _handle2int(_ffi.addressof(overlapped[0][0]))) + + at _ffi.callback("void(void*, int)") +def post_to_queue_callback(lpparameter, timerorwaitfired): + pdata = _ffi.cast("PostCallbackData*", lpparameter) + ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, timerorwaitfired, _ffi.cast("ULONG_PTR",0), pdata.Overlapped) + result = False + _winapi.free(pdata) + + +def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds): + data = _ffi.cast('PostCallbackData*', _winapi.malloc( _ffi.sizeof("PostCallbackData"))) + newwaitobject = _ffi.new("HANDLE*") + data[0].hCompletionPort = _int2handle(completionport) + data[0].Overlapped = _int2overlappedptr(ovaddress) + ret = _kernel32.RegisterWaitForSingleObject(newwaitobject, + _int2handle(object), + _ffi.cast("WAITORTIMERCALLBACK",post_to_queue_callback), + data, + miliseconds, + _kernel32.WT_EXECUTEINWAITTHREAD | _kernel32.WT_EXECUTEONLYONCE) + if not ret: + SetFromWindowsErr(0) + + return _handle2int(newwaitobject[0]) + +def ConnectPipe(address): + err = _winapi.ERROR_PIPE_BUSY + waddress = _ffi.new("wchar_t[]", address) + handle = _kernel32.CreateFileW(waddress, + _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, + 0, + _ffi.NULL, + _winapi.OPEN_EXISTING, + _winapi.FILE_FLAG_OVERLAPPED, + _ffi.NULL) + err = _kernel32.GetLastError() + + if handle == INVALID_HANDLE_VALUE or err == _winapi.ERROR_PIPE_BUSY: + SetFromWindowsErr(err) + + return _handle2int(handle) + +def UnregisterWaitEx(handle, event): + waithandle = _int2handle(handle) + waitevent = _int2handle(event) + + ret = _kernel32.UnregisterWaitEx(waithandle, waitevent) + + if not ret: + SetFromWindowsErr(0) + +def UnregisterWait(handle): + handle = _int2handle(handle) + + ret = _kernel32.UnregisterWait(handle) + + if not ret: + SetFromWindowsErr(0) + +def BindLocal(socket, family): + socket = _int2handle(socket) + if family == AF_INET: + addr = _ffi.new("struct sockaddr_in*") + addr[0].sin_family = AF_INET + addr[0].sin_port = 0 + addr[0].sin_addr.S_un.S_addr = INADDR_ANY + paddr = _ffi.cast("PSOCKADDR", addr) + result = _winsock2.bind(socket, paddr, _ffi.sizeof("struct sockaddr_in")) + elif family == AF_INET6: + addr = _ffi.new("struct sockaddr_in6*") + addr.sin6_family = AF_INET6 + addr.sin6_port = 0 + addr.sin6_addr = in6addr_any[0] + result = _winsock2.bind(socket, _ffi.cast("PSOCKADDR", addr), _ffi.sizeof("struct sockaddr_in")) + else: + raise ValueError() + + if result == SOCKET_ERROR: + SetFromWindowsErr(0) + +def HasOverlappedIoCompleted(overlapped): + return (overlapped.Internal != STATUS_PENDING) + +def parse_address(addressobj, address, length): + lengthptr = _ffi.new("INT*") + lengthptr[0] = length + if len(addressobj) == 2: + host,port = addressobj + address[0].sa_family = AF_INET + result = _winsock2.WSAStringToAddressW(host, AF_INET, _ffi.NULL, address, lengthptr) + if result < 0: + raise _winapi.WinError() + _ffi.cast("SOCKADDR_IN*",address)[0].sin_port = _winsock2.htons(port) + return address, lengthptr[0] + elif len(addressobj) == 4: + host, port, flowinfo, scopeid = addressobj + address.sa_family = AF_INET6 + result = _winsock2.WSAStringToAddressW(host, AF_INET6, _ffi.NULL, address, lengthptr) + address.sin6_port = _winsock2.htons(port) + address.sin6_flowinfo = flowinfo + address.sin6_scopeid = scopeid + return address, lengthptr[0] + else: + return -1 + + + + + + + diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -90,7 +90,6 @@ HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED; - DWORD WINAPI GetVersion(void); BOOL WINAPI CreatePipe(PHANDLE, PHANDLE, void *, DWORD); HANDLE WINAPI CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD, @@ -101,16 +100,17 @@ DWORD, DWORD, HANDLE); HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD); BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED); HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR); HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR); -VOID WINAPI SetEvent(HANDLE); +BOOL WINAPI SetEvent(HANDLE); +BOOL WINAPI CancelIo(HANDLE); BOOL WINAPI CancelIoEx(HANDLE, LPOVERLAPPED); BOOL WINAPI CloseHandle(HANDLE); DWORD WINAPI GetLastError(VOID); BOOL WINAPI GetOverlappedResult(HANDLE, LPOVERLAPPED, LPDWORD, BOOL); - HANDLE WINAPI GetCurrentProcess(void); BOOL WINAPI DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD); @@ -121,19 +121,171 @@ void *, BOOL, DWORD, wchar_t *, wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION); DWORD WINAPI WaitForSingleObject(HANDLE, DWORD); +DWORD WaitForMultipleObjects(DWORD, HANDLE*, BOOL, DWORD); BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD); BOOL WINAPI TerminateProcess(HANDLE, UINT); HANDLE WINAPI GetStdHandle(DWORD); DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD); - UINT WINAPI SetErrorMode(UINT); #define SEM_FAILCRITICALERRORS 0x0001 #define SEM_NOGPFAULTERRORBOX 0x0002 #define SEM_NOALIGNMENTFAULTEXCEPT 0x0004 #define SEM_NOOPENFILEERRORBOX 0x8000 + +typedef struct _PostCallbackData { + HANDLE hCompletionPort; + LPOVERLAPPED Overlapped; +} PostCallbackData, *LPPostCallbackData; + +typedef VOID (WINAPI *WAITORTIMERCALLBACK) (PVOID, BOOL); +BOOL WINAPI RegisterWaitForSingleObject(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, ULONG, ULONG); + +BOOL WINAPI PostQueuedCompletionStatus(HANDLE, DWORD, ULONG_PTR, LPOVERLAPPED); +BOOL WINAPI UnregisterWaitEx(HANDLE, HANDLE); +BOOL WINAPI UnregisterWait(HANDLE); + +BOOL WINAPI GetQueuedCompletionStatus(HANDLE, LPDWORD, ULONG**, LPOVERLAPPED*, DWORD); +HANDLE WINAPI CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD); + +BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); + +#define WT_EXECUTEINWAITTHREAD 0x00000004 +#define WT_EXECUTEONLYONCE 0x00000008 + +HANDLE GetProcessHeap(); +LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T); +BOOL HeapFree(HANDLE, DWORD, LPVOID); + """) -# -------------------- +# -------------------- Win Sock 2 ---------------------- + +ffi.cdef(""" +typedef struct _WSABUF { + ULONG len; + CHAR *buf; +} WSABUF, *LPWSABUF; + +typedef HANDLE SOCKET; +SOCKET __stdcall socket(int, int, int); +int closesocket(SOCKET); + + +typedef BOOL (__stdcall * LPFN_DISCONNECTEX) (SOCKET, LPOVERLAPPED, DWORD, DWORD); +typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE) (DWORD, DWORD, LPVOID); + +int __stdcall WSARecv(SOCKET, LPWSABUF, DWORD, LPDWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); +int __stdcall WSASend(SOCKET, LPWSABUF, DWORD, LPDWORD, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); +int __stdcall WSAIoctl(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); + + +typedef struct _GUID { + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[8]; +} GUID; + +typedef USHORT ADDRESS_FAMILY; + +typedef struct in6_addr { + union { + UCHAR Byte[16]; + USHORT Word[8]; + } u; +} IN6_ADDR, *PIN6_ADDR, *LPIN6_ADDR; + +typedef struct { + union { + struct { + ULONG Zone : 28; + ULONG Level : 4; + }; + ULONG Value; + }; +} SCOPE_ID, *PSCOPE_ID; + +typedef struct sockaddr_in6 { + ADDRESS_FAMILY sin6_family; + USHORT sin6_port; + ULONG sin6_flowinfo; + IN6_ADDR sin6_addr; + union { + ULONG sin6_scope_id; + SCOPE_ID sin6_scope_struct; + }; +} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH; + +typedef struct in_addr { + union { + struct { + UCHAR s_b1; + UCHAR s_b2; + UCHAR s_b3; + UCHAR s_b4; + } S_un_b; + struct { + USHORT s_w1; + USHORT s_w2; + } S_un_w; + ULONG S_addr; + } S_un; +} INADDR, *PINADDR; + +typedef struct sockaddr_in { + SHORT sin_family; + USHORT sin_port; + INADDR sin_addr; + CHAR sin_zero[8]; +} SOCKADDR_IN, *PSOCKADDR_IN, *LPSOCKADDR_IN; + +typedef struct sockaddr { + USHORT sa_family; + CHAR sa_data[14]; +} SOCKADDR, *PSOCKADDR, *LPSOCKADDR; + +int bind(SOCKET, const PSOCKADDR, int); + +#define MAX_PROTOCOL_CHAIN 7 + +typedef struct _WSAPROTOCOLCHAIN { + int ChainLen; + DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; +} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN; + +#define WSAPROTOCOL_LEN 255 + +typedef struct _WSAPROTOCOL_INFOW { + DWORD dwServiceFlags1; + DWORD dwServiceFlags2; + DWORD dwServiceFlags3; + DWORD dwServiceFlags4; + DWORD dwProviderFlags; + GUID ProviderId; + DWORD dwCatalogEntryId; + WSAPROTOCOLCHAIN ProtocolChain; + int iVersion; + int iAddressFamily; + int iMaxSockAddr; + int iMinSockAddr; + int iSocketType; + int iProtocol; + int iProtocolMaxOffset; + int iNetworkByteOrder; + int iSecurityScheme; + DWORD dwMessageSize; + DWORD dwProviderReserved; + WCHAR szProtocol[WSAPROTOCOL_LEN + 1]; +} WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW; + +int __stdcall WSAStringToAddressW(LPWSTR, int, LPWSAPROTOCOL_INFOW, LPSOCKADDR, int* ); + +typedef BOOL (WINAPI* AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const PSOCKADDR, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *DisconnectExPtr)(SOCKET, LPOVERLAPPED, DWORD, DWORD); + +USHORT htons(USHORT); +""") if __name__ == "__main__": ffi.compile() diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py --- a/lib_pypy/_pypy_winbase_cffi.py +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -3,8 +3,8 @@ ffi = _cffi_backend.FFI('_pypy_winbase_cffi', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\xAB\x03\x00\x00\x13\x11\x00\x00\xB0\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\xAA\x03\x00\x00\xA8\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\xA7\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x29\x11\x00\x00\x18\x03\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x2E\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x6B\x03\x00\x00\x49\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x49\x11\x00\x00\x49\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x33\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x66\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x00\x0F\x00\x00\x66\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\xA9\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xAB\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x6E\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x6B\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x71\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x49\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x77\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x6E\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\xB0\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x04\x09\x00\x00\x02\x09\x00\x00\x05\x09\x00\x00\x03\x09\x00\x00\x02\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\xAF\x03\x00\x00\x04\x01\x00\x00\x00\x01', - _globals = (b'\x00\x00\x27\x23CancelIoEx',0,b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x27\x23ConnectNamedPipe',0,b'\x00\x00\x6D\x23CreateEventA',0,b'\x00\x00\x73\x23CreateEventW',0,b'\x00\x00\x79\x23CreateFileA',0,b'\x00\x00\x9B\x23CreateFileW',0,b'\x00\x00\x82\x23CreateNamedPipeA',0,b'\x00\x00\x91\x23CreateNamedPipeW',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x48\x23CreateProcessW',0,b'\x00\x00\x3F\x23DuplicateHandle',0,b'\x00\x00\x8F\x23GetCurrentProcess',0,b'\x00\x00\x35\x23GetExitCodeProcess',0,b'\x00\x00\x63\x23GetLastError',0,b'\x00\x00\x5E\x23GetModuleFileNameW',0,b'\x00\x00\x2B\x23GetOverlappedResult',0,b'\x00\x00\x8C\x23GetStdHandle',0,b'\x00\x00\x63\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x57\x23SetErrorMode',0,b'\x00\x00\xA4\x23SetEvent',0,b'\x00\x00\x39\x23SetNamedPipeHandleState',0,b'\x00\x00\x31\x23TerminateProcess',0,b'\x00\x00\x5A\x23WaitForSingleObject',0,b'\x00\x00\x54\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x68\x23_getwch',0,b'\x00\x00\x68\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x6A\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x65\x23_ungetwch',0), - _struct_unions = ((b'\x00\x00\x00\xAD\x00\x00\x00\x03$1',b'\x00\x00\xAC\x11DUMMYSTRUCTNAME',b'\x00\x00\x15\x11Pointer'),(b'\x00\x00\x00\xAC\x00\x00\x00\x02$2',b'\x00\x00\x18\x11Offset',b'\x00\x00\x18\x11OffsetHigh'),(b'\x00\x00\x00\xA8\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\xAA\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x66\x11wShowWindow',b'\x00\x00\x66\x11cbReserved2',b'\x00\x00\xAE\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError'),(b'\x00\x00\x00\xA7\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x18\x11Internal',b'\x00\x00\x18\x11InternalHigh',b'\x00\x00\xAD\x11DUMMYUNIONNAME',b'\x00\x00\x15\x11hEvent'),(b'\x00\x00\x00\xA9\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x18\x11nLength',b'\x00\x00\x15\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle')), - _typenames = (b'\x00\x00\x00\x29LPOVERLAPPED',b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x6ELPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\xA7OVERLAPPED',b'\x00\x00\x00\xA8PROCESS_INFORMATION',b'\x00\x00\x00\x6EPSECURITY_ATTRIBUTES',b'\x00\x00\x00\xA9SECURITY_ATTRIBUTES',b'\x00\x00\x00\xAASTARTUPINFO',b'\x00\x00\x00\x66wint_t'), + _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x68\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x42\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x3B\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x4C\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x47\x03\x00\x01\x3C\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x32\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x48\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x2D\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x68\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xE2\x03\x00\x00\x07\x01\x00\x01\x4B\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xB3\x11\x00\x00\xB3\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xDD\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x00\x0F\x00\x00\xDD\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x41\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x4C\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEC\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xE2\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xEF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xB3\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF5\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xEC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x68\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x68\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x38\x03\x00\x00\x13\x09\x00\x01\x3A\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x3E\x03\x00\x00\x0E\x09\x00\x01\x40\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x46\x03\x00\x01\x45\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x4A\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x4C\x05\x00\x00\x00\x0E\x00\x01\x4C\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\x98\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x5F\x03\x00\x00\x04\x01\x00\x01\x5F\x05\x00\x00\x00\x10\x00\x01\x5F\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xDD\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xE2\x05\x00\x00\x01\x00', + _globals = (b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xEB\x23CreateEventA',0,b'\x00\x00\xF1\x23CreateEventW',0,b'\x00\x00\xF7\x23CreateFileA',0,b'\x00\x01\x24\x23CreateFileW',0,b'\x00\x01\x12\x23CreateIoCompletionPort',0,b'\x00\x01\x00\x23CreateNamedPipeA',0,b'\x00\x01\x1A\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xB9\x23CreateProcessW',0,b'\x00\x00\xA2\x23DuplicateHandle',0,b'\x00\x01\x18\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xDA\x23GetLastError',0,b'\x00\x00\xD5\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xE9\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x0F\x23GetStdHandle',0,b'\x00\x00\xDA\x23GetVersion',0,b'\x00\x00\xE4\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xC8\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xB2\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xCB\x23WaitForMultipleObjects',0,b'\x00\x00\xD1\x23WaitForSingleObject',0,b'\x00\x00\xAB\x23WriteFile',0,b'\x00\x00\xC5\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xDF\x23_getwch',0,b'\x00\x00\xDF\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE1\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xDC\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xDC\x23htons',0,b'\x00\x01\x0A\x23socket',0), + _struct_unions = ((b'\x00\x00\x01\x59\x00\x00\x00\x03$1',b'\x00\x01\x55\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x55\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x5A\x00\x00\x00\x03$3',b'\x00\x01\x60\x11Byte',b'\x00\x01\x66\x11Word'),(b'\x00\x00\x01\x5B\x00\x00\x00\x01$4',b'\x00\x01\x56\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x56\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x5C\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x40\x11sin6_scope_struct'),(b'\x00\x00\x01\x5D\x00\x00\x00\x03$7',b'\x00\x01\x57\x11S_un_b',b'\x00\x01\x58\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x57\x00\x00\x00\x02$8',b'\x00\x01\x5F\x11s_b1',b'\x00\x01\x5F\x11s_b2',b'\x00\x01\x5F\x11s_b3',b'\x00\x01\x5F\x11s_b4'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$9',b'\x00\x00\xDD\x11s_w1',b'\x00\x00\xDD\x11s_w2'),(b'\x00\x00\x01\x3C\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x40\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x5B\x11'),(b'\x00\x00\x01\x47\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xDD\x11wShowWindow',b'\x00\x00\xDD\x11cbReserved2',b'\x00\x01\x5E\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x36\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xDD\x11Data2',b'\x00\x00\xDD\x11Data3',b'\x00\x01\x62\x11Data4'),(b'\x00\x00\x01\x3B\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x59\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x3E\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x41\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x4A\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x64\x11ChainEntries'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x36\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x4A\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x69\x11szProtocol'),(b'\x00\x00\x01\x38\x00\x00\x00\x02in6_addr',b'\x00\x01\x5A\x11u'),(b'\x00\x00\x01\x3A\x00\x00\x00\x02in_addr',b'\x00\x01\x5D\x11S_un'),(b'\x00\x00\x01\x42\x00\x00\x00\x02sockaddr',b'\x00\x00\xDD\x11sa_family',b'\x00\x01\x4D\x11sa_data'),(b'\x00\x00\x01\x46\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x54\x11sin_family',b'\x00\x00\xDD\x11sin_port',b'\x00\x01\x3A\x11sin_addr',b'\x00\x01\x4F\x11sin_zero'),(b'\x00\x00\x01\x45\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xDD\x11sin6_family',b'\x00\x00\xDD\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x38\x11sin6_addr',b'\x00\x01\x5C\x11')), + _typenames = (b'\x00\x00\x00\xDDADDRESS_FAMILY',b'\x00\x00\x01\x53AcceptExPtr',b'\x00\x00\x01\x52ConnectExPtr',b'\x00\x00\x01\x51DisconnectExPtr',b'\x00\x00\x01\x36GUID',b'\x00\x00\x01\x38IN6_ADDR',b'\x00\x00\x01\x3AINADDR',b'\x00\x00\x01\x51LPFN_DISCONNECTEX',b'\x00\x00\x01\x37LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x3DLPPostCallbackData',b'\x00\x00\x00\xECLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x43LPSOCKADDR_IN',b'\x00\x00\x01\x44LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x49LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xB5LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x3BOVERLAPPED',b'\x00\x00\x01\x37PIN6_ADDR',b'\x00\x00\x01\x39PINADDR',b'\x00\x00\x01\x3CPROCESS_INFORMATION',b'\x00\x00\x01\x3FPSCOPE_ID',b'\x00\x00\x00\xECPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x43PSOCKADDR_IN',b'\x00\x00\x01\x44PSOCKADDR_IN6_LH',b'\x00\x00\x01\x3EPostCallbackData',b'\x00\x00\x01\x40SCOPE_ID',b'\x00\x00\x01\x41SECURITY_ATTRIBUTES',b'\x00\x00\x01\x42SOCKADDR',b'\x00\x00\x01\x46SOCKADDR_IN',b'\x00\x00\x01\x45SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x47STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x48WSABUF',b'\x00\x00\x01\x4AWSAPROTOCOLCHAIN',b'\x00\x00\x01\x4BWSAPROTOCOL_INFOW',b'\x00\x00\x00\xDDwint_t'), ) diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -17,10 +17,25 @@ NULL = _ffi.NULL # Now the _subprocess module implementation +def _WinError(type=WindowsError): + code, message = _ffi.getwinerror() + excep = type(None, message, None ,code) + raise excep -def _WinError(): - code, message = _ffi.getwinerror() - raise WindowsError(code, message) +# In CPython this function converts a windows error into a python object +# Not sure what we should do here. +def SetFromWindowsErr(err): + if err == 0: + err = _kernel32.GetLastError() + + if err == ERROR_CONNECTION_REFUSED: + type = ConnectionRefusedError + elif err == ERROR_CONNECTION_ABORTED: + type = ConnectionAbortedError + else: + type = WindowsError + + return _WinError(type) def _int2handle(val): return _ffi.cast("HANDLE", val) @@ -32,25 +47,25 @@ def CreatePipe(attributes, size): handles = _ffi.new("HANDLE[2]") - + res = _kernel32.CreatePipe(handles, handles + 1, NULL, size) if not res: - raise _WinError() + SetFromWindowsErr(0) return _handle2int(handles[0]), _handle2int(handles[1]) def CreateNamedPipe(*args): handle = _kernel32.CreateNamedPipeW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() - return handle + SetFromWindowsErr(0) + return _handle2int(handle) def CreateFile(*args): handle = _kernel32.CreateFileW(*args) if handle == INVALID_HANDLE_VALUE: - raise _WinError() - return handle + SetFromWindowsErr(0) + return _handle2int(handle) def SetNamedPipeHandleState(namedpipe, mode, max_collection_count, collect_data_timeout): d0 = _ffi.new('DWORD[1]', [mode]) @@ -79,20 +94,20 @@ def __del__(self): # do this somehow else - xxx err = _kernel32.GetLastError() bytes = _ffi.new('DWORD[1]') - o = overlapped[0] - if overlapped[0].pending: + o = self.overlapped[0] + if self.pending: if _kernel32.CancelIoEx(o.handle, o.overlapped) & \ self.GetOverlappedResult(o.handle, o.overlapped, _ffi.addressof(bytes), True): # The operation is no longer pending, nothing to do pass else: - raise RuntimeError('deleting an overlapped strucwith a pending operation not supported') + raise RuntimeError('deleting an overlapped struct with a pending operation not supported') @property def event(self): + xxx return None def GetOverlappedResult(self, wait): @@ -110,8 +125,8 @@ else: self.pending = 0 raise _WinError() - if self.completed and self.read_buffer: - if transferred != len(self.read_buffer): + if self.completed and self.readbuffer: + if transferred != len(self.readbuffer): raise _WinError() return transferred[0], err @@ -125,6 +140,7 @@ def ConnectNamedPipe(handle, overlapped=False): + handle = _int2handle(handle) if overlapped: ov = Overlapped(handle) else: @@ -140,10 +156,10 @@ _kernel32.SetEvent(ov.overlapped[0].hEvent) else: del ov - raise _WinError() + SetFromWindowsErr(err) return ov elif not success: - raise _WinError() + SetFromWindowsErr(0) def GetCurrentProcess(): return _handle2int(_kernel32.GetCurrentProcess()) @@ -217,6 +233,18 @@ return res +def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds): + if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS: + return None + + # CPython makes the wait interruptible by ctrl-c. We need to add this in at some point + res = _kernel32.WaitForMultipleObjects(len(handle_sequence), handle_sequence, waitflag, milliseconds) + + if res == WAIT_FAILED: + raise _WinError() + return int(res) + + def GetExitCodeProcess(handle): # CPython: the first argument is expected to be an integer. code = _ffi.new("DWORD[1]") @@ -260,6 +288,14 @@ raise _WinError() return _ffi.string(buf) +ZERO_MEMORY = 0x00000008 + +def malloc(size): + return _kernel32.HeapAlloc(_kernel32.GetProcessHeap(),ZERO_MEMORY,size) + +def free(voidptr): + _kernel32.HeapFree(_kernel32.GetProcessHeap(),0, voidptr) + # #define macros from WinBase.h and elsewhere STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 @@ -272,6 +308,7 @@ WAIT_OBJECT_0 = 0 WAIT_ABANDONED_0 = 0x80 WAIT_TIMEOUT = 0x102 +WAIT_FAILED = 0xFFFFFFFF CREATE_NEW_CONSOLE = 0x010 CREATE_NEW_PROCESS_GROUP = 0x200 CREATE_UNICODE_ENVIRONMENT = 0x400 @@ -281,11 +318,14 @@ ERROR_SUCCESS = 0 ERROR_NETNAME_DELETED = 64 ERROR_BROKEN_PIPE = 109 +ERROR_PIPE_BUSY = 231 ERROR_MORE_DATA = 234 ERROR_PIPE_CONNECTED = 535 ERROR_OPERATION_ABORTED = 995 ERROR_IO_INCOMPLETE = 996 ERROR_IO_PENDING = 997 +ERROR_CONNECTION_REFUSED = 1225 +ERROR_CONNECTION_ABORTED = 1236 PIPE_ACCESS_INBOUND = 0x00000001 PIPE_ACCESS_OUTBOUND = 0x00000002 @@ -299,11 +339,13 @@ PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000 PIPE_REJECT_REMOTE_CLIENTS = 0x00000008 +PIPE_UNLIMITED_INSTANCES = 255 + GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 GENERIC_EXECUTE= 0x20000000 GENERIC_ALL = 0x10000000 -INVALID_HANDLE_VALUE = -1 +INVALID_HANDLE_VALUE = _int2handle(-1) FILE_FLAG_WRITE_THROUGH = 0x80000000 FILE_FLAG_OVERLAPPED = 0x40000000 FILE_FLAG_NO_BUFFERING = 0x20000000 @@ -326,3 +368,5 @@ OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 +MAXIMUM_WAIT_OBJECTS = 64 + diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.12.2 +Version: 1.12.3 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.2" -__version_info__ = (1, 12, 2) +__version__ = "1.12.3" +__version_info__ = (1, 12, 3) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -223,7 +223,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.2" + "\ncompiled with cffi version: 1.12.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v7.1.1.rst @@ -0,0 +1,96 @@ +========================================= +PyPy v7.1.1: release of 2.7, and 3.6-beta +========================================= + +The PyPy team is proud to release a bug-fix release version 7.1.1 of PyPy, which +includes two different interpreters: + + - PyPy2.7, which is an interpreter supporting the syntax and the features of + Python 2.7 + + - PyPy3.6-beta: this is the second official release of PyPy to support 3.6 + features, although it is still considered beta quality. + +The interpreters are based on much the same codebase, thus the double +release. + +As always, this release is 100% compatible with the previous one and fixed +several issues and bugs raised by the growing community of PyPy users. +We strongly recommend updating. + +The PyPy3.6 release is still not production quality so your mileage may vary. +There are open issues with incomplete compatibility and c-extension support. + +You can download the v7.1.1 releases here: + + http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project. If PyPy is not quite good enough for your needs, we are available for +direct consulting work. + +We would also like to thank our contributors and encourage new people to join +the project. PyPy has many layers and we need help with all of them: `PyPy`_ +and `RPython`_ documentation improvements, tweaking popular modules to run +on pypy, or general `help`_ with making RPython's JIT even better. + +.. _`PyPy`: index.html +.. _`RPython`: https://rpython.readthedocs.org +.. _`help`: project-ideas.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7, 3.6. It's fast (`PyPy and CPython 2.7.x`_ performance +comparison) due to its integrated tracing JIT compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +This PyPy release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +Unfortunately at the moment of writing our ARM buildbots are out of service, +so for now we are **not** releasing any binary for the ARM architecture, +although PyPy does support ARM 32 bit processors. + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + + +Changelog +========= + +Changes shared across versions +* improve performance of ``u''.append`` +* Prevent a crash in ``zlib`` when flushing a closed stream +* Fix a few corener cases when encountering unicode values above 0x110000 +* Teach the JIT how to handle very large constant lists, sets, or dicts +* Fix building on ARM32 (issue 2984_) +* Fix a bug in register assignment in ARM32 +* Package windows DLLs needed by cffi modules next to the cffi c-extensions + (issue 2988_) +* Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem`` +* Fix memoryviews of ctype structures with padding, (cpython issue 32780_) + +Python 3.6 only + +* On win32, override some ``errno.E*`` values that were added to MSVC in v2010 + so that ``errno.E* == errno.WSAE*`` as in CPython +* Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the + AST level) +* ``str.maketrans`` was broken (issue 2991_) +* Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` + and ``'a' < buffer`` + +.. _2984: https://bitbucket.org/pypy/pypy/issues/2984 +.. _2991: https://bitbucket.org/pypy/pypy/issues/2991 +.. _2988: https://bitbucket.org/pypy/pypy/issues/2988 +.. _32780: https://bugs.python.org/issue32780 diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -8,3 +8,8 @@ .. branch: zlib-make-py3-go-boom Complain if you try to copy a flushed zlib decompress on py3 + +.. branch: winoverlapped + +Add support for async (overlapped) IO on Windows. + diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1067,9 +1067,10 @@ """ return None - def listview_utf8(self, w_list): - """ Return a list of unwrapped unicode out of a list of unicode. If the - argument is not a list or does not contain only unicode, return None. + def listview_ascii(self, w_list): + """ Return a list of unwrapped **ASCII** strings out of a list of + unicode. If the argument is not a list, does not contain only unicode, + or contains a unicode with non-ascii characters, return None. May return None anyway. """ return None diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py --- a/pypy/module/__pypy__/test/test_special.py +++ b/pypy/module/__pypy__/test/test_special.py @@ -82,7 +82,7 @@ l = [b"a", b"b", b"c"] assert strategy(l) == "BytesListStrategy" l = [u"a", u"b", u"c"] - assert strategy(l) == "UnicodeListStrategy" + assert strategy(l) == "AsciiListStrategy" l = [1.1, 2.2, 3.3] assert strategy(l) == "FloatListStrategy" l = [1, "b", 3] diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi from rpython.rtyper.lltypesystem import rffi -VERSION = "1.12.2" +VERSION = "1.12.3" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -1156,11 +1156,15 @@ elif mytype.typecode == 'c': return space.newbytes(item) elif mytype.typecode == 'u': - if ord(item) >= 0x110000: + code = r_uint(ord(item)) + try: + item = rutf8.unichr_as_utf8(code) + except rutf8.OutOfRange: raise oefmt(space.w_ValueError, - "array contains a unicode character out of " - "range(0x110000)") - return space.newtext(rutf8.unichr_as_utf8(ord(item)), 1) + "cannot operate on this array('u') because it contains" + " character %s not in range [U+0000; U+10ffff]" + " at index %d", 'U+%x' % code, idx) + return space.newtext(item, 1) assert 0, "unreachable" # interface diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -897,7 +897,13 @@ a = self.array('u', input_unicode) b = self.array('u', input_unicode) b.byteswap() - raises(ValueError, "a != b") + assert b[2] == u'\u0000' + raises(ValueError, "b[1]") # doesn't work + e = raises(ValueError, "a != b") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") assert str(a) == "array('u', %r)" % (input_unicode,) assert str(b) == ("array('u', )") diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -344,7 +344,7 @@ popitem delitem clear copy \ length w_keys values items \ iterkeys itervalues iteritems \ - listview_bytes listview_utf8 listview_int \ + listview_bytes listview_ascii listview_int \ view_as_kwargs".split() def make_method(method): @@ -491,7 +491,7 @@ def listview_bytes(self, w_dict): return None - def listview_utf8(self, w_dict): + def listview_ascii(self, w_dict): return None def listview_int(self, w_dict): @@ -1202,7 +1202,8 @@ assert key is not None return self.getitem(w_dict, self.space.newtext(key)) - ## def listview_utf8(self, w_dict): + ## def listview_ascii(self, w_dict): + ## XXX reimplement. Also warning: must return a list of _ascii_ ## return self.unerase(w_dict.dstorage).keys() def wrapkey(space, key): diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -97,13 +97,13 @@ return space.fromcache(BytesListStrategy) elif type(w_firstobj) is W_UnicodeObject and w_firstobj.is_ascii(): - # check for all-unicodes + # check for all-unicodes containing only ascii for i in range(1, len(list_w)): item = list_w[i] if type(item) is not W_UnicodeObject or not item.is_ascii(): break else: - return space.fromcache(UnicodeListStrategy) + return space.fromcache(AsciiListStrategy) elif type(w_firstobj) is W_FloatObject: # check for all-floats @@ -197,8 +197,8 @@ return W_ListObject.from_storage_and_strategy(space, storage, strategy) @staticmethod - def newlist_utf8(space, list_u): - strategy = space.fromcache(UnicodeListStrategy) + def newlist_ascii(space, list_u): + strategy = space.fromcache(AsciiListStrategy) storage = strategy.erase(list_u) return W_ListObject.from_storage_and_strategy(space, storage, strategy) @@ -336,10 +336,10 @@ not use the list strategy, return None.""" return self.strategy.getitems_bytes(self) - def getitems_utf8(self): + def getitems_ascii(self): """Return the items in the list as unwrapped unicodes. If the list does not use the list strategy, return None.""" - return self.strategy.getitems_utf8(self) + return self.strategy.getitems_ascii(self) def getitems_int(self): """Return the items in the list as unwrapped ints. If the list does not @@ -778,7 +778,7 @@ def getitems_bytes(self, w_list): return None - def getitems_utf8(self, w_list): + def getitems_ascii(self, w_list): return None def getitems_int(self, w_list): @@ -925,7 +925,7 @@ elif type(w_item) is W_BytesObject: strategy = self.space.fromcache(BytesListStrategy) elif type(w_item) is W_UnicodeObject and w_item.is_ascii(): - strategy = self.space.fromcache(UnicodeListStrategy) + strategy = self.space.fromcache(AsciiListStrategy) elif type(w_item) is W_FloatObject: strategy = self.space.fromcache(FloatListStrategy) else: @@ -1003,9 +1003,9 @@ w_list.lstorage = strategy.erase(byteslist[:]) return - unilist = space.listview_utf8(w_iterable) + unilist = space.listview_ascii(w_iterable) if unilist is not None: - w_list.strategy = strategy = space.fromcache(UnicodeListStrategy) + w_list.strategy = strategy = space.fromcache(AsciiListStrategy) # need to copy because intlist can share with w_iterable w_list.lstorage = strategy.erase(unilist[:]) return @@ -1967,7 +1967,7 @@ return self.unerase(w_list.lstorage) -class UnicodeListStrategy(ListStrategy): +class AsciiListStrategy(ListStrategy): import_from_mixin(AbstractUnwrappedStrategy) _none_value = "" @@ -1987,7 +1987,7 @@ return type(w_obj) is W_UnicodeObject and w_obj.is_ascii() def list_is_correct_type(self, w_list): - return w_list.strategy is self.space.fromcache(UnicodeListStrategy) + return w_list.strategy is self.space.fromcache(AsciiListStrategy) def sort(self, w_list, reverse): l = self.unerase(w_list.lstorage) @@ -1996,7 +1996,7 @@ if reverse: l.reverse() - def getitems_utf8(self, w_list): + def getitems_ascii(self, w_list): return self.unerase(w_list.lstorage) # _______________________________________________________ diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -333,7 +333,7 @@ def newlist_utf8(self, list_u, is_ascii): if is_ascii: - return W_ListObject.newlist_utf8(self, list_u) + return W_ListObject.newlist_ascii(self, list_u) return ObjSpace.newlist_utf8(self, list_u, False) @@ -542,19 +542,19 @@ return w_obj.getitems_bytes() return None - def listview_utf8(self, w_obj): + def listview_ascii(self, w_obj): # note: uses exact type checking for objects with strategies, # and isinstance() for others. See test_listobject.test_uses_custom... if type(w_obj) is W_ListObject: - return w_obj.getitems_utf8() + return w_obj.getitems_ascii() if type(w_obj) is W_DictObject: - return w_obj.listview_utf8() + return w_obj.listview_ascii() if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: - return w_obj.listview_utf8() + return w_obj.listview_ascii() if isinstance(w_obj, W_UnicodeObject) and self._uses_unicode_iter(w_obj): - return w_obj.listview_utf8() + return w_obj.listview_ascii() if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): - return w_obj.getitems_utf8() + return w_obj.getitems_ascii() return None def listview_int(self, w_obj): diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -86,9 +86,9 @@ """ If this is a string set return its contents as a list of uwnrapped strings. Otherwise return None. """ return self.strategy.listview_bytes(self) - def listview_utf8(self): + def listview_ascii(self): """ If this is a unicode set return its contents as a list of uwnrapped unicodes. Otherwise return None. """ - return self.strategy.listview_utf8(self) + return self.strategy.listview_ascii(self) def listview_int(self): """ If this is an int set return its contents as a list of uwnrapped ints. Otherwise return None. """ @@ -671,7 +671,7 @@ def listview_bytes(self, w_set): return None - def listview_utf8(self, w_set): + def listview_ascii(self, w_set): return None def listview_int(self, w_set): @@ -777,7 +777,7 @@ elif type(w_key) is W_BytesObject: strategy = self.space.fromcache(BytesSetStrategy) elif type(w_key) is W_UnicodeObject and w_key.is_ascii(): - strategy = self.space.fromcache(UnicodeSetStrategy) + strategy = self.space.fromcache(AsciiSetStrategy) elif self.space.type(w_key).compares_by_identity(): strategy = self.space.fromcache(IdentitySetStrategy) else: @@ -1239,7 +1239,7 @@ return BytesIteratorImplementation(self.space, self, w_set) -class UnicodeSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy): +class AsciiSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy): erase, unerase = rerased.new_erasing_pair("unicode") erase = staticmethod(erase) unerase = staticmethod(unerase) @@ -1253,7 +1253,7 @@ def get_empty_dict(self): return {} - def listview_utf8(self, w_set): + def listview_ascii(self, w_set): return self.unerase(w_set.sstorage).keys() def is_correct_type(self, w_key): @@ -1301,7 +1301,7 @@ def may_contain_equal_elements(self, strategy): if strategy is self.space.fromcache(BytesSetStrategy): return False - elif strategy is self.space.fromcache(UnicodeSetStrategy): + elif strategy is self.space.fromcache(AsciiSetStrategy): return False elif strategy is self.space.fromcache(EmptySetStrategy): return False @@ -1392,7 +1392,7 @@ return False if strategy is self.space.fromcache(BytesSetStrategy): return False - if strategy is self.space.fromcache(UnicodeSetStrategy): + if strategy is self.space.fromcache(AsciiSetStrategy): return False return True @@ -1585,9 +1585,9 @@ w_set.sstorage = strategy.get_storage_from_unwrapped_list(byteslist) return - unicodelist = space.listview_utf8(w_iterable) + unicodelist = space.listview_ascii(w_iterable) if unicodelist is not None: - strategy = space.fromcache(UnicodeSetStrategy) + strategy = space.fromcache(AsciiSetStrategy) w_set.strategy = strategy w_set.sstorage = strategy.get_storage_from_unwrapped_list(unicodelist) return @@ -1634,7 +1634,7 @@ if type(w_item) is not W_UnicodeObject or not w_item.is_ascii(): break else: - w_set.strategy = space.fromcache(UnicodeSetStrategy) + w_set.strategy = space.fromcache(AsciiSetStrategy) w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w) return diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -148,7 +148,7 @@ w = self.space.wrap w_d = self.space.newdict() w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(2))]) - assert self.space.listview_utf8(w_d) == ["a", "b"] + assert self.space.listview_ascii(w_d) == ["a", "b"] def test_listview_int_dict(self): w = self.space.wrap diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1403,6 +1403,10 @@ l1 = list(s) assert len(l1) == 1 + def test_unicode_bug_in_listview_utf8(self): + l1 = list(u'\u1234\u2345') + assert l1 == [u'\u1234', '\u2345'] + def test_list_from_set(self): l = ['a'] l.__init__(set('b')) diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -3,7 +3,7 @@ from pypy.objspace.std.listobject import ( W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, BytesListStrategy, RangeListStrategy, - SimpleRangeListStrategy, make_range_list, UnicodeListStrategy, + SimpleRangeListStrategy, make_range_list, AsciiListStrategy, IntOrFloatListStrategy) from pypy.objspace.std import listobject from pypy.objspace.std.test.test_listobject import TestW_ListObject @@ -21,7 +21,7 @@ assert isinstance(W_ListObject(space, [wb('a'), wb('b')]).strategy, BytesListStrategy) assert isinstance(W_ListObject(space, [w(u'a'), w(u'b')]).strategy, - UnicodeListStrategy) + AsciiListStrategy) assert isinstance(W_ListObject(space, [w(u'a'), wb('b')]).strategy, ObjectListStrategy) # mixed unicode and bytes @@ -47,7 +47,7 @@ l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) l.append(w(u'a')) - assert isinstance(l.strategy, UnicodeListStrategy) + assert isinstance(l.strategy, AsciiListStrategy) l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) @@ -76,9 +76,9 @@ def test_unicode_to_any(self): space = self.space l = W_ListObject(space, [space.wrap(u'a'), space.wrap(u'b'), space.wrap(u'c')]) - assert isinstance(l.strategy, UnicodeListStrategy) + assert isinstance(l.strategy, AsciiListStrategy) l.append(space.wrap(u'd')) - assert isinstance(l.strategy, UnicodeListStrategy) + assert isinstance(l.strategy, AsciiListStrategy) l.append(space.wrap(3)) assert isinstance(l.strategy, ObjectListStrategy) @@ -101,7 +101,7 @@ l.setitem(0, w('d')) assert space.eq_w(l.getitem(0), w('d')) - assert isinstance(l.strategy, UnicodeListStrategy) + assert isinstance(l.strategy, AsciiListStrategy) # IntStrategy to ObjectStrategy l = W_ListObject(space, [w(1),w(2),w(3)]) @@ -139,7 +139,7 @@ # UnicodeStrategy l = W_ListObject(space, [w(u'a'),w(u'b'),w(u'c')]) - assert isinstance(l.strategy, UnicodeListStrategy) + assert isinstance(l.strategy, AsciiListStrategy) l.insert(3, w(2)) assert isinstance(l.strategy, ObjectListStrategy) @@ -219,7 +219,7 @@ # UnicodeStrategy to ObjectStrategy l = W_ListObject(space, [w(u'a'), w(u'b'), w(u'c')]) - assert isinstance(l.strategy, UnicodeListStrategy) + assert isinstance(l.strategy, AsciiListStrategy) l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(l.strategy, ObjectListStrategy) @@ -270,7 +270,7 @@ l = W_ListObject(space, wrapitems([u"a",u"b",u"c",u"d",u"e"])) other = W_ListObject(space, wrapitems([u"a", u"b", u"c"])) keep_other_strategy(l, 0, 2, other.length(), other) - assert l.strategy is space.fromcache(UnicodeListStrategy) + assert l.strategy is space.fromcache(AsciiListStrategy) l = W_ListObject(space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5])) other = W_ListObject(space, []) @@ -340,7 +340,7 @@ empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) empty.extend(W_ListObject(space, [w(u"a"), w(u"b"), w(u"c")])) - assert isinstance(empty.strategy, UnicodeListStrategy) + assert isinstance(empty.strategy, AsciiListStrategy) empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) @@ -596,7 +596,7 @@ l1 = W_ListObject(self.space, [self.space.newbytes("eins"), self.space.newbytes("zwei")]) assert isinstance(l1.strategy, BytesListStrategy) l2 = W_ListObject(self.space, [self.space.newutf8("eins", 4), self.space.newutf8("zwei", 4)]) - assert isinstance(l2.strategy, UnicodeListStrategy) + assert isinstance(l2.strategy, AsciiListStrategy) l3 = W_ListObject(self.space, [self.space.newbytes("eins"), self.space.newutf8("zwei", 4)]) assert isinstance(l3.strategy, ObjectListStrategy) @@ -608,9 +608,9 @@ def test_listview_unicode(self): space = self.space - assert space.listview_utf8(space.wrap(1)) == None + assert space.listview_ascii(space.wrap(1)) == None w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')]) - assert space.listview_utf8(w_l) == ["a", "b"] + assert space.listview_ascii(w_l) == ["a", "b"] def test_string_join_uses_listview_bytes(self): space = self.space @@ -670,10 +670,10 @@ w_l4 = space.call_method(w_u, "rsplit", space.wrap(" ")) finally: del space.newlist - assert space.listview_utf8(w_l) == [u"a", u"b", u"c"] - assert space.listview_utf8(w_l2) == [u"a", u"b", u"c"] - assert space.listview_utf8(w_l3) == [u"a", u"b", u"c"] - assert space.listview_utf8(w_l4) == [u"a", u"b", u"c"] + assert space.listview_ascii(w_l) == [u"a", u"b", u"c"] + assert space.listview_ascii(w_l2) == [u"a", u"b", u"c"] + assert space.listview_ascii(w_l3) == [u"a", u"b", u"c"] + assert space.listview_ascii(w_l4) == [u"a", u"b", u"c"] def test_pop_without_argument_is_fast(self): space = self.space @@ -717,7 +717,7 @@ def test_listview_unicode_list(self): space = self.space w_l = W_ListObject(space, [space.wrap(u"a"), space.wrap(u"b")]) - assert self.space.listview_utf8(w_l) == [u"a", u"b"] + assert self.space.listview_ascii(w_l) == [u"a", u"b"] def test_listview_int_list(self): space = self.space diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -83,7 +83,7 @@ def test_create_set_from_list(self): from pypy.interpreter.baseobjspace import W_Root - from pypy.objspace.std.setobject import BytesSetStrategy, ObjectSetStrategy, UnicodeSetStrategy + from pypy.objspace.std.setobject import BytesSetStrategy, ObjectSetStrategy, AsciiSetStrategy from pypy.objspace.std.floatobject import W_FloatObject w = self.space.wrap @@ -108,8 +108,8 @@ w_list = self.space.iter(W_ListObject(self.space, [w(u"1"), w(u"2"), w(u"3")])) w_set = W_SetObject(self.space) _initialize_set(self.space, w_set, w_list) - #assert w_set.strategy is self.space.fromcache(UnicodeSetStrategy) - #assert w_set.strategy.unerase(w_set.sstorage) == {u"1":None, u"2":None, u"3":None} + assert w_set.strategy is self.space.fromcache(AsciiSetStrategy) + assert w_set.strategy.unerase(w_set.sstorage) == {u"1":None, u"2":None, u"3":None} w_list = W_ListObject(self.space, [w("1"), w(2), w("3")]) w_set = W_SetObject(self.space) @@ -1114,3 +1114,7 @@ assert len(items) == 2 items.add(first) assert items == set(d) + + def test_unicode_bug_in_listview_utf8(self): + l1 = set(u'\u1234\u2345') + assert l1 == set([u'\u1234', '\u2345']) diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py --- a/pypy/objspace/std/test/test_setstrategies.py +++ b/pypy/objspace/std/test/test_setstrategies.py @@ -3,7 +3,7 @@ from pypy.objspace.std.setobject import ( BytesIteratorImplementation, BytesSetStrategy, EmptySetStrategy, IntegerIteratorImplementation, IntegerSetStrategy, ObjectSetStrategy, - UnicodeIteratorImplementation, UnicodeSetStrategy) + UnicodeIteratorImplementation, AsciiSetStrategy) from pypy.objspace.std.listobject import W_ListObject class TestW_SetStrategies: @@ -31,8 +31,8 @@ s = W_SetObject(self.space, self.wrapped(["a", "b"], bytes=True)) assert s.strategy is self.space.fromcache(BytesSetStrategy) - #s = W_SetObject(self.space, self.wrapped([u"a", u"b"])) - #assert s.strategy is self.space.fromcache(UnicodeSetStrategy) + s = W_SetObject(self.space, self.wrapped([u"a", u"b"])) + assert s.strategy is self.space.fromcache(AsciiSetStrategy) def test_switch_to_object(self): s = W_SetObject(self.space, self.wrapped([1,2,3,4,5])) @@ -47,7 +47,7 @@ def test_switch_to_unicode(self): s = W_SetObject(self.space, self.wrapped([])) s.add(self.space.wrap(u"six")) - assert s.strategy is self.space.fromcache(UnicodeSetStrategy) + assert s.strategy is self.space.fromcache(AsciiSetStrategy) def test_symmetric_difference(self): s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5])) diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py --- a/pypy/objspace/std/test/test_stdobjspace.py +++ b/pypy/objspace/std/test/test_stdobjspace.py @@ -86,11 +86,6 @@ assert isinstance(w_x, W_UnicodeObject) assert w_x._utf8 == 'foo' # - # calling space.wrap() on a byte string which is not ASCII should - # never happen. Howeven it might happen while the py3k port is not - # 100% complete. In the meantime, try to return something more or less - # sensible instead of crashing with an RPython UnicodeError. - from pypy.objspace.std.unicodeobject import W_UnicodeObject - w_x = self.space.wrap('foo\xF0') - assert isinstance(w_x, W_UnicodeObject) - assert w_x._utf8 == 'foo\xF0' + # calling space.wrap() on a byte string which is not utf-8 should + # never happen. + py.test.raises(UnicodeDecodeError, self.space.wrap, 'foo\xF0') diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -28,7 +28,7 @@ def test_listview_unicode(self): w_str = self.space.newutf8('abcd', 4) - assert self.space.listview_utf8(w_str) == list("abcd") + assert self.space.listview_ascii(w_str) == list("abcd") def test_new_shortcut(self): space = self.space @@ -225,6 +225,14 @@ raises(TypeError, ','.join, [b'a']) exc = raises(TypeError, ''.join, ['a', 2, 3]) assert 'sequence item 1' in str(exc.value) + # unicode lists + check(''.join(['\u1234']), '\u1234') + check(''.join(['\u1234', '\u2345']), '\u1234\u2345') + check('\u1234'.join(['\u2345', '\u3456']), '\u2345\u1234\u3456') + # also checking passing a single unicode instead of a list + check(''.join('\u1234'), '\u1234') + check(''.join('\u1234\u2345'), '\u1234\u2345') + check('\u1234'.join('\u2345\u3456'), '\u2345\u1234\u3456') def test_contains(self): assert '' in 'abc' diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -821,8 +821,8 @@ raise oefmt(space.w_ValueError, "type name must not contain null characters") pos = surrogate_in_utf8(name) if pos >= 0: - raise oefmt(space.w_ValueError, "can't encode character %s in position " - "%d, surrogates not allowed", name[pos], pos) + raise oefmt(space.w_ValueError, "can't encode character in position " + "%d, surrogates not allowed", pos) dict_w = {} dictkeys_w = space.listview(w_dict) for w_key in dictkeys_w: @@ -927,8 +927,8 @@ raise oefmt(space.w_ValueError, "type name must not contain null characters") pos = surrogate_in_utf8(name) if pos >= 0: - raise oefmt(space.w_ValueError, "can't encode character %s in position " - "%d, surrogates not allowed", name[pos], pos) + raise oefmt(space.w_ValueError, "can't encode character in position " + "%d, surrogates not allowed", pos) w_type.name = name def descr_get__qualname__(space, w_type): diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -39,13 +39,10 @@ self._length = length self._index_storage = rutf8.null_storage() if not we_are_translated(): - try: - # best effort, too expensive to handle surrogates - ulength = rutf8.codepoints_in_utf(utf8str) - except: - ulength = length - assert ulength == length - + # utf8str must always be a valid utf8 string, except maybe with + # explicit surrogate characters---which .decode('utf-8') doesn't + # special-case in Python 2, which is exactly what we want here + assert length == len(utf8str.decode('utf-8')) @staticmethod @@ -99,8 +96,12 @@ def utf8_w(self, space): return self._utf8 - def listview_utf8(self): - return _create_list_from_unicode(self._utf8) + def listview_ascii(self): + if self.is_ascii(): + return [c for c in self._utf8] + # rpython note: can't use list() to return a list of strings + # (only a list of chars is supported) + return None def descr_iter(self, space): from pypy.objspace.std.iterobject import W_FastUnicodeIterObject @@ -572,7 +573,7 @@ _StringMethods_descr_join = descr_join def descr_join(self, space, w_list): - l = space.listview_utf8(w_list) + l = space.listview_ascii(w_list) if l is not None and self.is_ascii(): if len(l) == 1: return space.newutf8(l[0], len(l[0])) @@ -1851,12 +1852,6 @@ W_UnicodeObject.typedef.flag_sequence_bug_compat = True -def _create_list_from_unicode(value): - # need this helper function to allow the jit to look inside and inline - # listview_unicode - return [rutf8.unichr_as_utf8(r_uint(s), True) for s in rutf8.Utf8StringIterator(value)] - - W_UnicodeObject.EMPTY = W_UnicodeObject('', 0) # Helper for converting int/long this is called only from From pypy.commits at gmail.com Sun Apr 14 08:32:34 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 05:32:34 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-add_newdoc: close experimental branch Message-ID: <5cb32862.1c69fb81.cfd7c.7f02@mx.google.com> Author: Matti Picus Branch: cpyext-add_newdoc Changeset: r96480:a5bd01e6ba05 Date: 2019-04-14 15:28 +0300 http://bitbucket.org/pypy/pypy/changeset/a5bd01e6ba05/ Log: close experimental branch From pypy.commits at gmail.com Sun Apr 14 08:32:36 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 05:32:36 -0700 (PDT) Subject: [pypy-commit] pypy closed-branches: Merge closed head a5bd01e6ba05 on branch cpyext-add_newdoc Message-ID: <5cb32864.1c69fb81.8a91d.c614@mx.google.com> Author: Matti Picus Branch: closed-branches Changeset: r96481:b609357b8cc5 Date: 2019-04-14 15:28 +0300 http://bitbucket.org/pypy/pypy/changeset/b609357b8cc5/ Log: Merge closed head a5bd01e6ba05 on branch cpyext-add_newdoc From pypy.commits at gmail.com Sun Apr 14 08:32:38 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 05:32:38 -0700 (PDT) Subject: [pypy-commit] pypy closed-branches: re-close this branch Message-ID: <5cb32866.1c69fb81.793c7.af89@mx.google.com> Author: Matti Picus Branch: closed-branches Changeset: r96482:63e901aa89cb Date: 2019-04-14 15:28 +0300 http://bitbucket.org/pypy/pypy/changeset/63e901aa89cb/ Log: re-close this branch From pypy.commits at gmail.com Sun Apr 14 10:00:15 2019 From: pypy.commits at gmail.com (pganssle) Date: Sun, 14 Apr 2019 07:00:15 -0700 (PDT) Subject: [pypy-commit] pypy datetime_api_27: Add _FromTimestamp methods to CAPI capsule Message-ID: <5cb33cef.1c69fb81.793c7.b996@mx.google.com> Author: Paul Ganssle Branch: datetime_api_27 Changeset: r96483:d5b44bb7b84d Date: 2019-04-12 12:44 -0400 http://bitbucket.org/pypy/pypy/changeset/d5b44bb7b84d/ Log: Add _FromTimestamp methods to CAPI capsule The CPython CAPI capsule includes fromtimestamp constructors, but the current cpyext implementation does not, which causes some problems for people writing C extensions that use the capsule directly rather than the C macros. Closes bitbucket issue #2986: https://bitbucket.org/pypy/pypy/issues/2986 diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -67,6 +67,14 @@ _PyDelta_FromDelta.api_func.functype, _PyDelta_FromDelta.api_func.get_wrapper(space)) + datetimeAPI.c_DateTime_FromTimestamp = llhelper( + _PyDateTime_FromTimestamp.api_func.functype, + _PyDateTime_FromTimestamp.api_func.get_wrapper(space)) + + datetimeAPI.c_Date_FromTimestamp = llhelper( + _PyDate_FromTimestamp.api_func.functype, + _PyDate_FromTimestamp.api_func.get_wrapper(space)) + state.datetimeAPI.append(datetimeAPI) return state.datetimeAPI[0] @@ -243,8 +251,16 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("datetime")) + return _PyDateTime_FromTimestamp(space, w_type, w_args, None) + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def _PyDateTime_FromTimestamp(space, w_type, w_args, w_kwds): + """Implementation of datetime.fromtimestamp that matches the signature for + PyDatetimeCAPI.DateTime_FromTimestamp + """ w_method = space.getattr(w_type, space.newtext("fromtimestamp")) - return space.call(w_method, w_args) + + return space.call(w_method, w_args, w_kwds=w_kwds) @cpython_api([PyObject], PyObject) def PyDate_FromTimestamp(space, w_args): @@ -253,6 +269,12 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("date")) + return _PyDate_FromTimestamp(space, w_type, w_args) + + at cpython_api([PyObject, PyObject], PyObject) +def _PyDate_FromTimestamp(space, w_type, w_args): + """Implementation of date.fromtimestamp that matches the signature for + PyDatetimeCAPI.Date_FromTimestamp""" w_method = space.getattr(w_type, space.newtext("fromtimestamp")) return space.call(w_method, w_args) diff --git a/pypy/module/cpyext/parse/cpyext_datetime.h b/pypy/module/cpyext/parse/cpyext_datetime.h --- a/pypy/module/cpyext/parse/cpyext_datetime.h +++ b/pypy/module/cpyext/parse/cpyext_datetime.h @@ -13,6 +13,10 @@ PyObject*, PyTypeObject*); PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); } PyDateTime_CAPI; typedef struct diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -146,6 +146,41 @@ 2000, 6, 6, 6, 6, 6, 6, Py_None, PyDateTimeAPI->DateTimeType); """), + ("new_datetime_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(2, ts, Py_None); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL); + Py_DECREF(tsargs); + return rv; + """), + ("new_dt_fromts_tzinfo", "METH_O", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *tskwargs = PyDict_New(); + + Py_INCREF(args); + PyDict_SetItemString(tskwargs, "tz", args); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, tskwargs); + Py_DECREF(tsargs); + Py_DECREF(tskwargs); + return rv; + """), + ("new_date_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(1430366400.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs); + Py_DECREF(tsargs); + return rv; + """), + ], prologue='#include "datetime.h"\n') import datetime assert module.new_date() == datetime.date(2000, 6, 6) @@ -153,6 +188,28 @@ assert module.new_datetime() == datetime.datetime( 2000, 6, 6, 6, 6, 6, 6) + class UTC(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(hours=0) + + def dst(self, dt): + return datetime.timedelta(0) + + def tzname(self, dt): + return "UTC" + + utc = UTC() + + # .fromtimestamp tests + assert (module.new_datetime_fromtimestamp() == + datetime.datetime.fromtimestamp(200000.0)) + + assert (module.new_dt_fromts_tzinfo(utc) == + datetime.datetime.fromtimestamp(200000.0, tz=utc)) + + assert (module.new_date_fromtimestamp() == + datetime.date.fromtimestamp(1430366400.0)) + def test_macros(self): module = self.import_extension('foo', [ ("test_date_macros", "METH_NOARGS", @@ -305,16 +362,18 @@ """), ], prologue='#include "datetime.h"\n') from datetime import tzinfo, datetime, timedelta, time + # copied from datetime documentation class GMT1(tzinfo): def __del__(self): - print 'deleting GMT1' + print('deleting GMT1') def utcoffset(self, dt): return timedelta(hours=1) + self.dst(dt) def dst(self, dt): return timedelta(0) def tzname(self,dt): return "GMT +1" + gmt1 = GMT1() dt1 = module.time_with_tzinfo(gmt1) assert dt1 == time(6, 6, 6, 6, gmt1) From pypy.commits at gmail.com Sun Apr 14 10:00:17 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 07:00:17 -0700 (PDT) Subject: [pypy-commit] pypy datetime_api_27: typo Message-ID: <5cb33cf1.1c69fb81.eaa47.c981@mx.google.com> Author: Matti Picus Branch: datetime_api_27 Changeset: r96484:8a60117eee9d Date: 2019-04-14 16:32 +0300 http://bitbucket.org/pypy/pypy/changeset/8a60117eee9d/ Log: typo diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -256,7 +256,7 @@ @cpython_api([PyObject, PyObject, PyObject], PyObject) def _PyDateTime_FromTimestamp(space, w_type, w_args, w_kwds): """Implementation of datetime.fromtimestamp that matches the signature for - PyDatetimeCAPI.DateTime_FromTimestamp + PyDateTimeCAPI.DateTime_FromTimestamp """ w_method = space.getattr(w_type, space.newtext("fromtimestamp")) @@ -274,7 +274,7 @@ @cpython_api([PyObject, PyObject], PyObject) def _PyDate_FromTimestamp(space, w_type, w_args): """Implementation of date.fromtimestamp that matches the signature for - PyDatetimeCAPI.Date_FromTimestamp""" + PyDateTimeCAPI.Date_FromTimestamp""" w_method = space.getattr(w_type, space.newtext("fromtimestamp")) return space.call(w_method, w_args) From pypy.commits at gmail.com Sun Apr 14 10:00:19 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 07:00:19 -0700 (PDT) Subject: [pypy-commit] pypy datetime_api_27: document and close branch to be merged Message-ID: <5cb33cf3.1c69fb81.e443.ba47@mx.google.com> Author: Matti Picus Branch: datetime_api_27 Changeset: r96485:5799459b8a2a Date: 2019-04-14 16:40 +0300 http://bitbucket.org/pypy/pypy/changeset/5799459b8a2a/ Log: document and close branch to be merged diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -12,3 +12,7 @@ .. branch: jit-cleanup Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ + +.. branch: datetime_api_27 + +Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` From pypy.commits at gmail.com Sun Apr 14 10:00:21 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 07:00:21 -0700 (PDT) Subject: [pypy-commit] pypy default: merge datetime_api_27 which provides Date*_FromTimestamp Message-ID: <5cb33cf5.1c69fb81.8c3c3.3bab@mx.google.com> Author: Matti Picus Branch: Changeset: r96486:2a381b55d56f Date: 2019-04-14 16:40 +0300 http://bitbucket.org/pypy/pypy/changeset/2a381b55d56f/ Log: merge datetime_api_27 which provides Date*_FromTimestamp diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -12,3 +12,7 @@ .. branch: jit-cleanup Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ + +.. branch: datetime_api_27 + +Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -67,6 +67,14 @@ _PyDelta_FromDelta.api_func.functype, _PyDelta_FromDelta.api_func.get_wrapper(space)) + datetimeAPI.c_DateTime_FromTimestamp = llhelper( + _PyDateTime_FromTimestamp.api_func.functype, + _PyDateTime_FromTimestamp.api_func.get_wrapper(space)) + + datetimeAPI.c_Date_FromTimestamp = llhelper( + _PyDate_FromTimestamp.api_func.functype, + _PyDate_FromTimestamp.api_func.get_wrapper(space)) + state.datetimeAPI.append(datetimeAPI) return state.datetimeAPI[0] @@ -243,8 +251,16 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("datetime")) + return _PyDateTime_FromTimestamp(space, w_type, w_args, None) + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def _PyDateTime_FromTimestamp(space, w_type, w_args, w_kwds): + """Implementation of datetime.fromtimestamp that matches the signature for + PyDateTimeCAPI.DateTime_FromTimestamp + """ w_method = space.getattr(w_type, space.newtext("fromtimestamp")) - return space.call(w_method, w_args) + + return space.call(w_method, w_args, w_kwds=w_kwds) @cpython_api([PyObject], PyObject) def PyDate_FromTimestamp(space, w_args): @@ -253,6 +269,12 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("date")) + return _PyDate_FromTimestamp(space, w_type, w_args) + + at cpython_api([PyObject, PyObject], PyObject) +def _PyDate_FromTimestamp(space, w_type, w_args): + """Implementation of date.fromtimestamp that matches the signature for + PyDateTimeCAPI.Date_FromTimestamp""" w_method = space.getattr(w_type, space.newtext("fromtimestamp")) return space.call(w_method, w_args) diff --git a/pypy/module/cpyext/parse/cpyext_datetime.h b/pypy/module/cpyext/parse/cpyext_datetime.h --- a/pypy/module/cpyext/parse/cpyext_datetime.h +++ b/pypy/module/cpyext/parse/cpyext_datetime.h @@ -13,6 +13,10 @@ PyObject*, PyTypeObject*); PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); } PyDateTime_CAPI; typedef struct diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -146,6 +146,41 @@ 2000, 6, 6, 6, 6, 6, 6, Py_None, PyDateTimeAPI->DateTimeType); """), + ("new_datetime_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(2, ts, Py_None); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL); + Py_DECREF(tsargs); + return rv; + """), + ("new_dt_fromts_tzinfo", "METH_O", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *tskwargs = PyDict_New(); + + Py_INCREF(args); + PyDict_SetItemString(tskwargs, "tz", args); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, tskwargs); + Py_DECREF(tsargs); + Py_DECREF(tskwargs); + return rv; + """), + ("new_date_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(1430366400.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs); + Py_DECREF(tsargs); + return rv; + """), + ], prologue='#include "datetime.h"\n') import datetime assert module.new_date() == datetime.date(2000, 6, 6) @@ -153,6 +188,28 @@ assert module.new_datetime() == datetime.datetime( 2000, 6, 6, 6, 6, 6, 6) + class UTC(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(hours=0) + + def dst(self, dt): + return datetime.timedelta(0) + + def tzname(self, dt): + return "UTC" + + utc = UTC() + + # .fromtimestamp tests + assert (module.new_datetime_fromtimestamp() == + datetime.datetime.fromtimestamp(200000.0)) + + assert (module.new_dt_fromts_tzinfo(utc) == + datetime.datetime.fromtimestamp(200000.0, tz=utc)) + + assert (module.new_date_fromtimestamp() == + datetime.date.fromtimestamp(1430366400.0)) + def test_macros(self): module = self.import_extension('foo', [ ("test_date_macros", "METH_NOARGS", @@ -305,16 +362,18 @@ """), ], prologue='#include "datetime.h"\n') from datetime import tzinfo, datetime, timedelta, time + # copied from datetime documentation class GMT1(tzinfo): def __del__(self): - print 'deleting GMT1' + print('deleting GMT1') def utcoffset(self, dt): return timedelta(hours=1) + self.dst(dt) def dst(self, dt): return timedelta(0) def tzname(self,dt): return "GMT +1" + gmt1 = GMT1() dt1 = module.time_with_tzinfo(gmt1) assert dt1 == time(6, 6, 6, 6, gmt1) From pypy.commits at gmail.com Sun Apr 14 10:00:23 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 07:00:23 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: merge default into branch Message-ID: <5cb33cf7.1c69fb81.48f82.98e4@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96487:569233e35ecd Date: 2019-04-14 16:41 +0300 http://bitbucket.org/pypy/pypy/changeset/569233e35ecd/ Log: merge default into branch diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -110,6 +110,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -125,7 +126,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -254,6 +254,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -403,6 +404,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -77,6 +77,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -92,7 +93,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -221,6 +221,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -370,6 +371,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -79,6 +79,7 @@ (issue 2988_) * Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem`` * Fix memoryviews of ctype structures with padding, (cpython issue 32780_) +* CFFI updated to as-yet-unreleased 1.12.3 Python 3.6 only @@ -89,8 +90,12 @@ * ``str.maketrans`` was broken (issue 2991_) * Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` and ``'a' < buffer`` +* Support ``_overlapped`` and asyncio on win32 +* Fix an issue where ``''.join(list_of_strings)`` would rarely confuse utf8 and + bytes (issue 2997_) .. _2984: https://bitbucket.org/pypy/pypy/issues/2984 .. _2991: https://bitbucket.org/pypy/pypy/issues/2991 .. _2988: https://bitbucket.org/pypy/pypy/issues/2988 +.. _2997: https://bitbucket.org/pypy/pypy/issues/2997 .. _32780: https://bugs.python.org/issue32780 diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -12,3 +12,7 @@ .. branch: jit-cleanup Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ + +.. branch: datetime_api_27 + +Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -67,6 +67,14 @@ _PyDelta_FromDelta.api_func.functype, _PyDelta_FromDelta.api_func.get_wrapper(space)) + datetimeAPI.c_DateTime_FromTimestamp = llhelper( + _PyDateTime_FromTimestamp.api_func.functype, + _PyDateTime_FromTimestamp.api_func.get_wrapper(space)) + + datetimeAPI.c_Date_FromTimestamp = llhelper( + _PyDate_FromTimestamp.api_func.functype, + _PyDate_FromTimestamp.api_func.get_wrapper(space)) + state.datetimeAPI.append(datetimeAPI) return state.datetimeAPI[0] @@ -243,8 +251,16 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("datetime")) + return _PyDateTime_FromTimestamp(space, w_type, w_args, None) + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def _PyDateTime_FromTimestamp(space, w_type, w_args, w_kwds): + """Implementation of datetime.fromtimestamp that matches the signature for + PyDateTimeCAPI.DateTime_FromTimestamp + """ w_method = space.getattr(w_type, space.newtext("fromtimestamp")) - return space.call(w_method, w_args) + + return space.call(w_method, w_args, w_kwds=w_kwds) @cpython_api([PyObject], PyObject) def PyDate_FromTimestamp(space, w_args): @@ -253,6 +269,12 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("date")) + return _PyDate_FromTimestamp(space, w_type, w_args) + + at cpython_api([PyObject, PyObject], PyObject) +def _PyDate_FromTimestamp(space, w_type, w_args): + """Implementation of date.fromtimestamp that matches the signature for + PyDateTimeCAPI.Date_FromTimestamp""" w_method = space.getattr(w_type, space.newtext("fromtimestamp")) return space.call(w_method, w_args) diff --git a/pypy/module/cpyext/parse/cpyext_datetime.h b/pypy/module/cpyext/parse/cpyext_datetime.h --- a/pypy/module/cpyext/parse/cpyext_datetime.h +++ b/pypy/module/cpyext/parse/cpyext_datetime.h @@ -13,6 +13,10 @@ PyObject*, PyTypeObject*); PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); } PyDateTime_CAPI; typedef struct diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -146,6 +146,41 @@ 2000, 6, 6, 6, 6, 6, 6, Py_None, PyDateTimeAPI->DateTimeType); """), + ("new_datetime_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(2, ts, Py_None); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL); + Py_DECREF(tsargs); + return rv; + """), + ("new_dt_fromts_tzinfo", "METH_O", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *tskwargs = PyDict_New(); + + Py_INCREF(args); + PyDict_SetItemString(tskwargs, "tz", args); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, tskwargs); + Py_DECREF(tsargs); + Py_DECREF(tskwargs); + return rv; + """), + ("new_date_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(1430366400.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs); + Py_DECREF(tsargs); + return rv; + """), + ], prologue='#include "datetime.h"\n') import datetime assert module.new_date() == datetime.date(2000, 6, 6) @@ -153,6 +188,28 @@ assert module.new_datetime() == datetime.datetime( 2000, 6, 6, 6, 6, 6, 6) + class UTC(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(hours=0) + + def dst(self, dt): + return datetime.timedelta(0) + + def tzname(self, dt): + return "UTC" + + utc = UTC() + + # .fromtimestamp tests + assert (module.new_datetime_fromtimestamp() == + datetime.datetime.fromtimestamp(200000.0)) + + assert (module.new_dt_fromts_tzinfo(utc) == + datetime.datetime.fromtimestamp(200000.0, tz=utc)) + + assert (module.new_date_fromtimestamp() == + datetime.date.fromtimestamp(1430366400.0)) + def test_macros(self): module = self.import_extension('foo', [ ("test_date_macros", "METH_NOARGS", @@ -305,6 +362,7 @@ """), ], prologue='#include "datetime.h"\n') from datetime import tzinfo, datetime, timedelta, time + # copied from datetime documentation class GMT1(tzinfo): def __del__(self): @@ -315,6 +373,7 @@ return timedelta(0) def tzname(self,dt): return "GMT +1" + gmt1 = GMT1() dt1 = module.time_with_tzinfo(gmt1) assert dt1 == time(6, 6, 6, 6, gmt1) From pypy.commits at gmail.com Sun Apr 14 10:00:25 2019 From: pypy.commits at gmail.com (pganssle) Date: Sun, 14 Apr 2019 07:00:25 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Use built-in UTC object in tzinfo test Message-ID: <5cb33cf9.1c69fb81.31eef.97be@mx.google.com> Author: Paul Ganssle Branch: py3.6 Changeset: r96488:8cb9d2e352b4 Date: 2019-04-12 16:35 -0400 http://bitbucket.org/pypy/pypy/changeset/8cb9d2e352b4/ Log: Use built-in UTC object in tzinfo test In Python 3.6, there is a built-in UTC object, so there is no need to make a custom one for this test. diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -188,17 +188,7 @@ assert module.new_datetime() == datetime.datetime( 2000, 6, 6, 6, 6, 6, 6) - class UTC(datetime.tzinfo): - def utcoffset(self, dt): - return datetime.timedelta(hours=0) - - def dst(self, dt): - return datetime.timedelta(0) - - def tzname(self, dt): - return "UTC" - - utc = UTC() + utc = datetime.timezone.utc # .fromtimestamp tests assert (module.new_datetime_fromtimestamp() == From pypy.commits at gmail.com Sun Apr 14 10:39:37 2019 From: pypy.commits at gmail.com (fijal) Date: Sun, 14 Apr 2019 07:39:37 -0700 (PDT) Subject: [pypy-commit] pypy arm64: implement int ops Message-ID: <5cb34629.1c69fb81.587a4.58fd@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96489:27c1f4063137 Date: 2019-04-12 12:45 +0000 http://bitbucket.org/pypy/pypy/changeset/27c1f4063137/ Log: implement int ops diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -114,6 +114,11 @@ base = 0b11001011001 self.write32((base << 21) | (rm << 16) | (0b11 << 13) | (rn << 5) | (rd)) + def SUB_rr_shifted(self, rd, rn, rm, shift=0): + base = 0b11001011000 + assert shift == 0 + self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) + def MUL_rr(self, rd, rn, rm): base = 0b10011011000 self.write32((base << 21) | (rm << 16) | (0b11111 << 10) | (rn << 5) | rd) @@ -142,6 +147,10 @@ base = 0b11001010000 self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) + def MVN_rr(self, rd, rm): + base = 0b10101010001 + self.write32((base << 21) | (rm << 16) | (0b11111 << 5)| rd) + def CMP_rr(self, rn, rm): base = 0b11101011000 self.write32((base << 21) | (rm << 16) | (rn << 5) | 0b11111) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -12,10 +12,7 @@ def emit_op(self, op, arglocs): l0, l1, res = arglocs - if l1.is_imm(): - self.mc.CMP_ri(l0.value, l1.getint()) - else: - self.mc.CMP_rr(l0.value, l1.value) + self.emit_int_comp_op(op, l0, l1) self.mc.CSET_r_flag(res.value, c.get_opposite_of(flag)) emit_op.__name__ = name return emit_op @@ -88,24 +85,22 @@ l0, l1, res = arglocs self.mc.UMULH_rr(res.value, l0.value, l1.value) - def emit_int_comp_op(self, op, arglocs): - l0, l1 = arglocs - + def emit_int_comp_op(self, op, l0, l1): if l1.is_imm(): self.mc.CMP_ri(l0.value, l1.getint()) else: self.mc.CMP_rr(l0.value, l1.value) def emit_comp_op_int_lt(self, op, arglocs): - self.emit_int_comp_op(op, arglocs) + self.emit_int_comp_op(op, arglocs[0], arglocs[1]) return c.LT def emit_comp_op_int_le(self, op, arglocs): - self.emit_int_comp_op(op, arglocs) + self.emit_int_comp_op(op, arglocs[0], arglocs[1]) return c.LE def emit_comp_op_int_eq(self, op, arglocs): - self.emit_int_comp_op(op, arglocs) + self.emit_int_comp_op(op, arglocs[0], arglocs[1]) return c.EQ emit_op_int_lt = gen_comp_op('emit_op_int_lt', c.LT) @@ -115,6 +110,31 @@ emit_op_int_eq = gen_comp_op('emit_op_int_eq', c.EQ) emit_op_int_ne = gen_comp_op('emit_op_int_ne', c.NE) + emit_op_uint_lt = gen_comp_op('emit_op_uint_lt', c.LO) + emit_op_uint_gt = gen_comp_op('emit_op_uint_gt', c.HI) + emit_op_uint_le = gen_comp_op('emit_op_uint_le', c.LS) + emit_op_uint_ge = gen_comp_op('emit_op_uint_ge', c.HS) + + def emit_op_int_is_true(self, op, arglocs): + reg, res = arglocs + + self.mc.CMP_ri(reg.value, 0) + self.mc.CSET_r_flag(res.value, c.EQ) + + def emit_op_int_is_zero(self, op, arglocs): + reg, res = arglocs + + self.mc.CMP_ri(reg.value, 0) + self.mc.CSET_r_flag(res.value, c.NE) + + def emit_op_int_neg(self, op, arglocs): + reg, res = arglocs + self.mc.SUB_rr_shifted(res.value, r.xzr.value, reg.value) + + def emit_op_int_invert(self, op, arglocs): + reg, res = arglocs + self.mc.MVN_rr(res.value, reg.value) + def emit_op_increment_debug_counter(self, op, arglocs): return # XXXX base_loc, value_loc = arglocs diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -385,6 +385,23 @@ prepare_op_int_ge = prepare_op_int_le prepare_op_int_eq = prepare_op_int_le prepare_op_int_ne = prepare_op_int_le + prepare_op_uint_lt = prepare_op_int_le + prepare_op_uint_le = prepare_op_int_le + prepare_op_uint_gt = prepare_op_int_le + prepare_op_uint_ge = prepare_op_int_le + + def prepare_unary(self, op): + a0 = op.getarg(0) + assert not isinstance(a0, Const) + reg = self.make_sure_var_in_reg(a0) + self.possibly_free_vars_for_op(op) + res = self.force_allocate_reg(op) + return [reg, res] + + prepare_op_int_is_true = prepare_unary + prepare_op_int_is_zero = prepare_unary + prepare_op_int_neg = prepare_unary + prepare_op_int_invert = prepare_unary def prepare_op_label(self, op): descr = op.getdescr() From pypy.commits at gmail.com Sun Apr 14 10:39:39 2019 From: pypy.commits at gmail.com (fijal) Date: Sun, 14 Apr 2019 07:39:39 -0700 (PDT) Subject: [pypy-commit] pypy arm64: overflow ops (except mul_ovf) Message-ID: <5cb3462b.1c69fb81.ab7f8.35af@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96490:ba9733af746e Date: 2019-04-14 13:30 +0000 http://bitbucket.org/pypy/pypy/changeset/ba9733af746e/ Log: overflow ops (except mul_ovf) diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -1,2 +1,3 @@ * int_add - IMM * int_cmp - IMM +* *_ovf - merging operations \ No newline at end of file diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -606,7 +606,11 @@ regalloc.possibly_free_vars_for_op(op) elif not we_are_translated() and op.getopnum() == rop.FORCE_SPILL: regalloc.prepare_force_spill(op) - elif i < len(operations) - 1 and regalloc.next_op_can_accept_cc(operations, i): + elif i < len(operations) - 1 and (regalloc.next_op_can_accept_cc(operations, i) or + operations[i].is_ovf()): + if operations[i].is_ovf(): + assert operations[i + 1].getopnum() in [rop.GUARD_OVERFLOW, + rop.GUARD_NO_OVERFLOW] guard_op = operations[i + 1] guard_num = guard_op.getopnum() arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op) diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -65,14 +65,14 @@ assert 0 <= immed < 1 << 16 self.write32((base << 21) | (immed << 5) | rd) - def ADD_ri(self, rd, rn, constant): - base = 0b1001000100 + def ADD_ri(self, rd, rn, constant, s=0): + base = 0b1001000100 | (s << 7) assert 0 <= constant < 4096 self.write32((base << 22) | (constant << 10) | (rn << 5) | rd) - def SUB_ri(self, rd, rn, constant): - base = 0b1101000100 + def SUB_ri(self, rd, rn, constant, s=0): + base = 0b1101000100 | (s << 7) assert 0 <= constant < 4096 self.write32((base << 22) | (constant << 10) | (rn << 5) | rd) @@ -106,12 +106,12 @@ assert offset & 0x3 == 0 self.write32((base << 24) | ((0x7ffff & (offset >> 2)) << 5) | rt) - def ADD_rr(self, rd, rn, rm): - base = 0b10001011000 + def ADD_rr(self, rd, rn, rm, s=0): + base = 0b10001011000 | (s << 8) self.write32((base << 21) | (rm << 16) | (rn << 5) | (rd)) - def SUB_rr(self, rd, rn, rm): - base = 0b11001011001 + def SUB_rr(self, rd, rn, rm, s=0): + base = 0b11001011001 | (s << 8) self.write32((base << 21) | (rm << 16) | (0b11 << 13) | (rn << 5) | (rd)) def SUB_rr_shifted(self, rd, rn, rm, shift=0): @@ -151,6 +151,14 @@ base = 0b10101010001 self.write32((base << 21) | (rm << 16) | (0b11111 << 5)| rd) + def SMULL_rr(self, rd, rn, rm): + base = 0b10011011001 + self.write32((base << 21) | (rm << 16) | (0b11111 << 10) | (rn << 5) | rd) + + def SMULH_rr(self, rd, rn, rm): + base = 0b10011011010 + self.write32((base << 21) | (rm << 16) | (0b11111 << 10) | (rn << 5) | rd) + def CMP_rr(self, rn, rm): base = 0b11101011000 self.write32((base << 21) | (rm << 16) | (rn << 5) | 0b11111) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -18,45 +18,55 @@ return emit_op class ResOpAssembler(BaseAssembler): - def emit_op_int_add(self, op, arglocs): - return self.int_add_impl(op, arglocs) - def int_sub_impl(self, op, arglocs, flags=0): l0, l1, res = arglocs if flags: - xxx s = 1 else: s = 0 if l1.is_imm(): value = l1.getint() assert value >= 0 - self.mc.SUB_ri(res.value, l0.value, value) + self.mc.SUB_ri(res.value, l0.value, value, s) else: - self.mc.SUB_rr(res.value, l0.value, l1.value) + self.mc.SUB_rr(res.value, l0.value, l1.value, s) def emit_op_int_sub(self, op, arglocs): self.int_sub_impl(op, arglocs) - emit_op_nursery_ptr_increment = emit_op_int_add - def int_add_impl(self, op, arglocs, ovfcheck=False): l0, l1, res = arglocs assert not l0.is_imm() if ovfcheck: - XXX s = 1 else: s = 0 if l1.is_imm(): - self.mc.ADD_ri(res.value, l0.value, l1.value) + self.mc.ADD_ri(res.value, l0.value, l1.value, s) else: - self.mc.ADD_rr(res.value, l0.value, l1.value) + self.mc.ADD_rr(res.value, l0.value, l1.value, s) + + def emit_op_int_add(self, op, arglocs): + self.int_add_impl(op, arglocs) + emit_op_nursery_ptr_increment = emit_op_int_add + + def emit_comp_op_int_add_ovf(self, op, arglocs): + self.int_add_impl(op, arglocs, True) + + def emit_comp_op_int_sub_ovf(self, op, arglocs): + self.int_sub_impl(op, arglocs, True) def emit_op_int_mul(self, op, arglocs): reg1, reg2, res = arglocs self.mc.MUL_rr(res.value, reg1.value, reg2.value) + def emit_comp_op_int_mul_ovf(self, op, arglocs): + reg1, reg2, res = arglocs + self.mc.MUL_rr(res.value, reg1.value, reg2.value) + xxx # what to do here? + self.mc.SMULH_rr(res.value, reg1.value, reg2.value) + self.mc.CMP_ri(r.ip0.value, 0) + def emit_op_int_and(self, op, arglocs): l0, l1, res = arglocs self.mc.AND_rr(res.value, l0.value, l1.value) @@ -175,9 +185,11 @@ def emit_guard_op_guard_true(self, guard_op, fcond, arglocs): self._emit_guard(guard_op, fcond, arglocs) + emit_guard_op_guard_no_overflow = emit_guard_op_guard_true def emit_guard_op_guard_false(self, guard_op, fcond, arglocs): self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs) + emit_guard_op_guard_overflow = emit_guard_op_guard_false def load_condition_into_cc(self, loc): if not loc.is_core_reg(): diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -1,6 +1,7 @@ from rpython.jit.backend.aarch64 import registers as r from rpython.jit.backend.aarch64 import locations +from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.aarch64.arch import WORD, JITFRAME_FIXED_SIZE from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, @@ -298,7 +299,7 @@ self.free_temp_vars() return [base_loc, value_loc] - def prepare_int_ri(self, op): + def prepare_int_ri(self, op, res_in_cc): boxes = op.getarglist() a0, a1 = boxes imm_a0 = check_imm_box(a0) @@ -314,9 +315,12 @@ l1 = self.make_sure_var_in_reg(a1, boxes) self.possibly_free_vars_for_op(op) res = self.force_allocate_reg(op) + # note that we always allocate res, even if res_in_cc is True, + # that only means overflow is in CC return [l0, l1, res] - prepare_op_int_add = prepare_int_ri + def prepare_op_int_add(self, op): + return self.prepare_int_ri(op, False) def prepare_op_int_sub(self, op): boxes = op.getarglist() @@ -332,6 +336,10 @@ res = self.force_allocate_reg(op) return [l0, l1, res] + def prepare_comp_op_int_sub_ovf(self, op, res_in_cc): + # ignore res_in_cc + return self.prepare_op_int_sub(op) + def prepare_op_int_mul(self, op): boxes = op.getarglist() a0, a1 = boxes @@ -345,6 +353,9 @@ self.possibly_free_var(op) return [reg1, reg2, res] + def prepare_comp_op_int_mul_ovf(self, op, res_in_cc): + return self.prepare_op_int_mul(op) + # some of those have forms of imm that they accept, but they're rather # obscure. Can be future optimization prepare_op_int_and = prepare_op_int_mul @@ -470,10 +481,19 @@ prepare_guard_op_guard_true = guard_impl prepare_guard_op_guard_false = guard_impl + def prepare_guard_op_guard_overflow(self, guard_op, prev_op): + self.assembler.dispatch_comparison(prev_op) + # result in CC + if prev_op.opnum == rop.INT_MUL_OVF: + return self._guard_impl(guard_op), c.GT + return self._guard_impl(guard_op), c.VC + prepare_guard_op_guard_no_overflow = prepare_guard_op_guard_overflow + prepare_op_guard_true = _guard_impl prepare_op_guard_false = _guard_impl prepare_op_nursery_ptr_increment = prepare_op_int_add + prepare_comp_op_int_add_ovf = prepare_int_ri def prepare_op_jump(self, op): assert self.jump_target_descr is None From pypy.commits at gmail.com Sun Apr 14 16:50:28 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 13:50:28 -0700 (PDT) Subject: [pypy-commit] pypy default: update index of release notes Message-ID: <5cb39d14.1c69fb81.8207c.25fc@mx.google.com> Author: Matti Picus Branch: Changeset: r96491:ebdfe9c517c3 Date: 2019-04-14 23:49 +0300 http://bitbucket.org/pypy/pypy/changeset/ebdfe9c517c3/ Log: update index of release notes diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-v7.1.1.rst release-v7.1.0.rst release-v7.0.0.rst release-v6.0.0.rst From pypy.commits at gmail.com Sun Apr 14 16:53:03 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 13:53:03 -0700 (PDT) Subject: [pypy-commit] pypy default: fix formatting of release note Message-ID: <5cb39daf.1c69fb81.b94d.21bd@mx.google.com> Author: Matti Picus Branch: Changeset: r96492:aad43009d972 Date: 2019-04-14 23:52 +0300 http://bitbucket.org/pypy/pypy/changeset/aad43009d972/ Log: fix formatting of release note diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -68,10 +68,11 @@ Changelog ========= -Changes shared across versions -* improve performance of ``u''.append`` +Changes shared across versions: + +* Improve performance of ``u''.append`` * Prevent a crash in ``zlib`` when flushing a closed stream -* Fix a few corener cases when encountering unicode values above 0x110000 +* Fix a few corner cases when encountering unicode values above 0x110000 * Teach the JIT how to handle very large constant lists, sets, or dicts * Fix building on ARM32 (issue 2984_) * Fix a bug in register assignment in ARM32 @@ -81,9 +82,9 @@ * Fix memoryviews of ctype structures with padding, (cpython issue 32780_) * CFFI updated to as-yet-unreleased 1.12.3 -Python 3.6 only +Python 3.6 only: -* On win32, override some ``errno.E*`` values that were added to MSVC in v2010 +* Override some ``errno.E*`` values that were added to MSVC in v2010 so that ``errno.E* == errno.WSAE*`` as in CPython * Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the AST level) From pypy.commits at gmail.com Sun Apr 14 17:36:44 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 14:36:44 -0700 (PDT) Subject: [pypy-commit] pypy default: formatting, index missing whatsnew Message-ID: <5cb3a7ec.1c69fb81.b3644.d49b@mx.google.com> Author: Matti Picus Branch: Changeset: r96493:005bf0d4bd35 Date: 2019-04-15 00:36 +0300 http://bitbucket.org/pypy/pypy/changeset/005bf0d4bd35/ Log: formatting, index missing whatsnew diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-pypy2-7.1.0.rst whatsnew-pypy2-7.0.0.rst whatsnew-pypy2-6.0.0.rst whatsnew-pypy2-5.10.0.rst diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -71,8 +71,11 @@ Changes shared across versions: * Improve performance of ``u''.append`` + * Prevent a crash in ``zlib`` when flushing a closed stream + * Fix a few corner cases when encountering unicode values above 0x110000 + * Teach the JIT how to handle very large constant lists, sets, or dicts * Fix building on ARM32 (issue 2984_) * Fix a bug in register assignment in ARM32 From pypy.commits at gmail.com Sun Apr 14 18:38:01 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 14 Apr 2019 15:38:01 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: add rudimentary context manager for "with pytest.raises()" in apptests Message-ID: <5cb3b649.1c69fb81.e443.060e@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96494:0f6d909ffb0c Date: 2019-04-15 01:37 +0300 http://bitbucket.org/pypy/pypy/changeset/0f6d909ffb0c/ Log: add rudimentary context manager for "with pytest.raises()" in apptests diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -83,7 +83,11 @@ __builtins__.py3k_skip = skip class ExceptionWrapper: pass - def raises(exc, func, *args, **kwargs): + def raises(exc, *args, **kwargs): + if not args: + return RaisesContext(exc) + func = args[0] + args = args[1:] import os try: if isinstance(func, str): @@ -101,6 +105,22 @@ return res else: raise AssertionError("DID NOT RAISE") + + class RaisesContext(object): + def __init__(self, expected_exception): + self.expected_exception = expected_exception + self.excinfo = None + + def __enter__(self): + return self + + def __exit__(self, *tp): + __tracebackhide__ = True + if tp[0] is None: + pytest.fail("DID NOT RAISE") + self.value = tp[1] + return issubclass(tp[0], self.expected_exception) + __builtins__.raises = raises class Test: pass From pypy.commits at gmail.com Mon Apr 15 11:09:48 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 15 Apr 2019 08:09:48 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: Move try_disabling_unroll logic up to MetaInterp.compile_loop() Message-ID: <5cb49ebc.1c69fb81.f1c83.3dae@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96495:9aea58ad1da8 Date: 2019-04-14 02:00 +0100 http://bitbucket.org/pypy/pypy/changeset/9aea58ad1da8/ Log: Move try_disabling_unroll logic up to MetaInterp.compile_loop() diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -3,21 +3,22 @@ from rpython.rtyper.annlowlevel import ( cast_instance_to_gcref, cast_gcref_to_instance) from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.debug import debug_start, debug_stop, debug_print, have_debug_prints +from rpython.rlib.debug import ( + debug_start, debug_stop, debug_print, have_debug_prints) from rpython.rlib.rarithmetic import r_uint, intmask from rpython.rlib import rstack from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside from rpython.rlib.rjitlog import rjitlog as jl -from rpython.jit.metainterp.resoperation import ResOperation, rop,\ - get_deep_immutable_oplist, OpHelpers, InputArgInt, InputArgRef,\ - InputArgFloat -from rpython.jit.metainterp.history import (TreeLoop, Const, JitCellToken, +from rpython.jit.metainterp.resoperation import ( + ResOperation, rop, get_deep_immutable_oplist, OpHelpers, InputArgInt, + InputArgRef, InputArgFloat) +from rpython.jit.metainterp.history import (TreeLoop, JitCellToken, TargetToken, AbstractFailDescr, ConstInt) from rpython.jit.metainterp import history, jitexc from rpython.jit.metainterp.optimize import InvalidLoop -from rpython.jit.metainterp.resume import (PENDINGFIELDSP, - ResumeDataDirectReader, AccumInfo) +from rpython.jit.metainterp.resume import ( + PENDINGFIELDSP, ResumeDataDirectReader) from rpython.jit.metainterp.resumecode import NUMBERING from rpython.jit.metainterp.support import adr2int from rpython.jit.codewriter import longlong @@ -28,6 +29,9 @@ raise SwitchToBlackhole(Counters.ABORT_BRIDGE) class CompileData(object): + """ An object that accumulates all of the necessary info for + the optimization phase, but does not actually have any other state + """ memo = None log_noopt = True @@ -36,9 +40,7 @@ arg.set_forwarded(None) class PreambleCompileData(CompileData): - """ An object that accumulates all of the necessary info for - the optimization phase, but does not actually have any other state - + """ This is the case of label() ops label() """ def __init__(self, trace, runtime_boxes, call_pure_results=None, @@ -204,7 +206,6 @@ # ____________________________________________________________ - def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts, cut_at): from rpython.jit.metainterp.optimizeopt import optimize_trace @@ -242,11 +243,11 @@ return target_token def compile_loop(metainterp, greenkey, start, inputargs, jumpargs, - full_preamble_needed=True, try_disabling_unroll=False): + use_unroll=True): """Try to compile a new procedure by closing the current history back to the first operation. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling + from rpython.jit.metainterp.optimizeopt import optimize_trace metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd @@ -258,14 +259,6 @@ faildescr=None, entry_bridge=False) # enable_opts = jitdriver_sd.warmstate.enable_opts - use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) - if try_disabling_unroll: - if not use_unroll: - return None - enable_opts = enable_opts.copy() - del enable_opts['unroll'] - use_unroll = False - jitcell_token = make_jitcell_token(jitdriver_sd) cut_at = history.get_trace_position() history.record(rop.JUMP, jumpargs, None, descr=jitcell_token) @@ -344,7 +337,7 @@ """Try to compile a new procedure by closing the current history back to the first operation. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling + from rpython.jit.metainterp.optimizeopt import optimize_trace trace = metainterp.history.trace.cut_trace_from(start, inputargs) metainterp_sd = metainterp.staticdata @@ -360,8 +353,6 @@ cut = history.get_trace_position() history.record(rop.JUMP, jumpargs[:], None, descr=loop_jitcell_token) enable_opts = jitdriver_sd.warmstate.enable_opts - use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) - assert use_unroll call_pure_results = metainterp.call_pure_results loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state, call_pure_results=call_pure_results, @@ -1039,7 +1030,7 @@ to some existing place. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace, use_unrolling + from rpython.jit.metainterp.optimizeopt import optimize_trace # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. @@ -1075,7 +1066,6 @@ data = SimpleCompileData(trace, resumestorage, call_pure_results=call_pure_results, enable_opts=enable_opts) - use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts) try: info, newops = optimize_trace( metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo) diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -31,9 +31,6 @@ assert ENABLE_ALL_OPTS == ALL_OPTS_NAMES, ( 'please fix rlib/jit.py to say ENABLE_ALL_OPTS = %r' % (ALL_OPTS_NAMES,)) -def use_unrolling(cpu, enable_opts): - return cpu.supports_guard_gc_type and 'unroll' in enable_opts - def build_opt_chain(enable_opts): optimizations = [] for name, opt in unroll_all_opts: diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2733,14 +2733,21 @@ self.resumekey, exported_state) else: - target_token = compile.compile_loop(self, greenkey, start, - original_boxes[num_green_args:], - live_arg_boxes[num_green_args:], - try_disabling_unroll=try_disabling_unroll) + use_unroll = (self.staticdata.cpu.supports_guard_gc_type and + 'unroll' in self.jitdriver_sd.warmstate.enable_opts) + if try_disabling_unroll: + if not use_unroll: + return + use_unroll = False + target_token = compile.compile_loop( + self, greenkey, start, original_boxes[num_green_args:], + live_arg_boxes[num_green_args:], use_unroll=use_unroll) if target_token is not None: assert isinstance(target_token, TargetToken) - self.jitdriver_sd.warmstate.attach_procedure_to_interp(greenkey, target_token.targeting_jitcell_token) - self.staticdata.stats.add_jitcell_token(target_token.targeting_jitcell_token) + self.jitdriver_sd.warmstate.attach_procedure_to_interp( + greenkey, target_token.targeting_jitcell_token) + self.staticdata.stats.add_jitcell_token( + target_token.targeting_jitcell_token) if target_token is not None: # raise if it *worked* correctly assert isinstance(target_token, TargetToken) diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -9,6 +9,7 @@ from rpython.jit.metainterp import history from rpython.jit.metainterp.test.support import LLJitMixin, noConst from rpython.jit.metainterp.warmspot import get_stats +from rpython.jit.metainterp.pyjitpl import MetaInterp from rpython.rlib import rerased from rpython.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside, loop_invariant, elidable, promote, jit_debug, assert_green, @@ -2883,10 +2884,11 @@ i += 1 return i # - def my_optimize_trace(*args, **kwds): - raise InvalidLoop - old_optimize_trace = optimizeopt.optimize_trace - optimizeopt.optimize_trace = my_optimize_trace + def my_compile_loop(self, original_boxes, live_arg_boxes, start, + try_disabling_unroll=False, exported_state=None): + return None + old_compile_loop = MetaInterp.compile_loop + MetaInterp.compile_loop = my_compile_loop try: res = self.meta_interp(f, [23, 4]) assert res == 23 @@ -2898,13 +2900,11 @@ self.check_trace_count(0) self.check_aborted_count(2) finally: - optimizeopt.optimize_trace = old_optimize_trace + MetaInterp.compile_loop = old_compile_loop def test_max_unroll_loops_retry_without_unroll(self): if not self.basic: py.test.skip("unrolling") - from rpython.jit.metainterp.optimize import InvalidLoop - from rpython.jit.metainterp import optimizeopt myjitdriver = JitDriver(greens = [], reds = ['n', 'i']) # def f(n, limit): @@ -2918,19 +2918,19 @@ return i # seen = [] - def my_optimize_trace(metainterp_sd, jitdriver_sd, data, memo=None): - use_unrolling = ('unroll' in data.enable_opts) - seen.append(use_unrolling) - raise InvalidLoop - old_optimize_trace = optimizeopt.optimize_trace - optimizeopt.optimize_trace = my_optimize_trace + def my_compile_loop(self, original_boxes, live_arg_boxes, start, + try_disabling_unroll=False, exported_state=None): + seen.append(try_disabling_unroll) + return None + old_compile_loop = MetaInterp.compile_loop + MetaInterp.compile_loop = my_compile_loop try: res = self.meta_interp(f, [23, 4]) assert res == 23 assert False in seen assert True in seen finally: - optimizeopt.optimize_trace = old_optimize_trace + MetaInterp.compile_loop = old_compile_loop def test_retrace_limit_with_extra_guards(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', diff --git a/rpython/jit/metainterp/test/test_compile.py b/rpython/jit/metainterp/test/test_compile.py --- a/rpython/jit/metainterp/test/test_compile.py +++ b/rpython/jit/metainterp/test/test_compile.py @@ -102,10 +102,10 @@ metainterp.history.trace = t # greenkey = 'faked' - target_token = compile_loop(metainterp, greenkey, (0, 0, 0), - t.inputargs, - [t._mapping[x] for x in loop.operations[-1].getarglist()], - None) + target_token = compile_loop( + metainterp, greenkey, (0, 0, 0), t.inputargs, + [t._mapping[x] for x in loop.operations[-1].getarglist()], + use_unroll=False) jitcell_token = target_token.targeting_jitcell_token assert jitcell_token == target_token.original_jitcell_token assert jitcell_token.target_tokens == [target_token] From pypy.commits at gmail.com Mon Apr 15 13:16:57 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 15 Apr 2019 10:16:57 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: test, fix fscode and also win32, fixes issue 2985 Message-ID: <5cb4bc89.1c69fb81.2fea2.0b56@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96496:df2790e6e32f Date: 2019-04-15 20:13 +0300 http://bitbucket.org/pypy/pypy/changeset/df2790e6e32f/ Log: test, fix fscode and also win32, fixes issue 2985 diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -69,10 +69,10 @@ self.w_obj = w_obj def as_bytes(self): - return self.space.bytesbuf0_w(self.w_obj) + return self.space.fsencode_w(self.w_obj) def as_unicode(self): - ret = self.space.fsdecode_w(self.w_obj) + ret = self.space.fsdecode_w(self.w_obj).decode('utf-8') if u'\x00' in ret: raise oefmt(self.space.w_ValueError, "embedded null character") return ret diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -96,10 +96,19 @@ cls.w_confstr_result = space.wrap(os.confstr(confstr_name)) cls.w_SIGABRT = space.wrap(signal.SIGABRT) cls.w_python = space.wrap(sys.executable) + cls.w_platform = space.wrap(sys.platform) if hasattr(os, 'major'): cls.w_expected_major_12345 = space.wrap(os.major(12345)) cls.w_expected_minor_12345 = space.wrap(os.minor(12345)) cls.w_udir = space.wrap(str(udir)) + cls.w_Path = space.appexec([], """(): + class Path: + def __init__(self, _path): + self._path =_path + def __fspath__(self): + return self._path + return Path + """) def setup_method(self, meth): if getattr(meth, 'need_sparse_files', False): @@ -401,10 +410,7 @@ path = self.path3 with open(path, 'wb'): pass - class Path: - def __fspath__(self): - return path - os.unlink(Path()) + os.unlink(self.Path()) def test_times(self): """ @@ -1076,7 +1082,7 @@ os.closerange(start, stop) for fd in fds: os.close(fd) # should not have been closed - if sys.platform == 'win32' and not we_are_translated(): + if self.platform == 'win32' and not we_are_translated(): # XXX kills the host interpreter untranslated for fd in range(start, stop): raises(OSError, os.fstat, fd) # should have been closed @@ -1224,17 +1230,12 @@ posix.unlink(bytes_dir + '/somelink'.encode()) def test_symlink_fspath(self): - class Path: - def __init__(self, b): - self.path = b - def __fspath__(self): - return self.path posix = self.posix bytes_dir = self.bytes_dir if bytes_dir is None: skip("encoding not good enough") - dest = Path(bytes_dir + b"/file.txt") - posix.symlink(Path(bytes_dir + b"/somefile"), dest) + dest = self.Path(bytes_dir + b"/file.txt") + posix.symlink(self.Path(bytes_dir + b"/somefile"), dest) try: with open(dest) as f: data = f.read() @@ -1548,6 +1549,7 @@ return 4 raises(TypeError, self.posix.fspath, WrongSample()) + raises(OSError, self.posix.replace, self.Path('nonexistentfile1'), 'bok') if hasattr(rposix, 'getxattr'): def test_xattr_simple(self): diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -1262,18 +1262,16 @@ @replace_os_function('rename') @specialize.argtype(0, 1) def rename(path1, path2): - if not _WIN32: - handle_posix_error('rename', - c_rename(_as_bytes0(path1), _as_bytes0(path2))) - else: + if _WIN32: traits = _preferred_traits2(path1, path2) win32traits = make_win32_traits(traits) path1 = traits.as_str0(path1) path2 = traits.as_str0(path2) - assert isinstance(path1, unicode) - assert isinstance(path2, unicode) if not win32traits.MoveFileEx(path1, path2, 0): raise rwin32.lastSavedWindowsError() + else: + handle_posix_error('rename', + c_rename(_as_bytes0(path1), _as_bytes0(path2))) @specialize.argtype(0, 1) def replace(path1, path2): @@ -1282,8 +1280,6 @@ win32traits = make_win32_traits(traits) path1 = traits.as_str0(path1) path2 = traits.as_str0(path2) - assert isinstance(path1, unicode) - assert isinstance(path2, unicode) ret = win32traits.MoveFileEx(path1, path2, win32traits.MOVEFILE_REPLACE_EXISTING) if not ret: From pypy.commits at gmail.com Mon Apr 15 13:32:17 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 15 Apr 2019 10:32:17 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: stdint.h exists on msvc 2010 and up, which should be used for python compilation Message-ID: <5cb4c021.1c69fb81.5174e.ce80@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96497:25affebcac5f Date: 2019-04-15 14:48 +0300 http://bitbucket.org/pypy/pypy/changeset/25affebcac5f/ Log: stdint.h exists on msvc 2010 and up, which should be used for python compilation diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -18,6 +18,7 @@ # define PyAPI_DATA(RTYPE) extern PyAPI_FUNC(RTYPE) # define Py_LOCAL_INLINE(type) static inline type #else +# include # define MS_WIN32 1 # define MS_WINDOWS 1 # ifdef _MSC_VER From pypy.commits at gmail.com Mon Apr 15 13:32:19 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 15 Apr 2019 10:32:19 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: marshal.h exists in PyPy since v7.0 Message-ID: <5cb4c023.1c69fb81.80d2a.11b8@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96498:4f0cad9e23bc Date: 2019-04-15 14:54 +0300 http://bitbucket.org/pypy/pypy/changeset/4f0cad9e23bc/ Log: marshal.h exists in PyPy since v7.0 diff --git a/lib_pypy/_testcapimodule.c b/lib_pypy/_testcapimodule.c --- a/lib_pypy/_testcapimodule.c +++ b/lib_pypy/_testcapimodule.c @@ -14,7 +14,7 @@ #include #include "structmember.h" #include "datetime.h" -// #include "marshal.h" +#include "marshal.h" #include #ifdef MS_WINDOWS From pypy.commits at gmail.com Mon Apr 15 15:06:32 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 15 Apr 2019 12:06:32 -0700 (PDT) Subject: [pypy-commit] pypy default: synchronize with py3.6 from df2790e6e32f Message-ID: <5cb4d638.1c69fb81.e7494.75f1@mx.google.com> Author: Matti Picus Branch: Changeset: r96500:2fbfe4373fd9 Date: 2019-04-15 22:01 +0300 http://bitbucket.org/pypy/pypy/changeset/2fbfe4373fd9/ Log: synchronize with py3.6 from df2790e6e32f diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -109,9 +109,6 @@ wchar_t const* file, unsigned int line, uintptr_t pReserved) { - wprintf(L"Invalid parameter detected in function %s." - L" File: %s Line: %d\\n", function, file, line); - wprintf(L"Expression: %s\\n", expression); } RPY_EXTERN void* enter_suppress_iph(void) @@ -1265,16 +1262,16 @@ @replace_os_function('rename') @specialize.argtype(0, 1) def rename(path1, path2): - if not _WIN32: - handle_posix_error('rename', - c_rename(_as_bytes0(path1), _as_bytes0(path2))) - else: + if _WIN32: traits = _preferred_traits2(path1, path2) win32traits = make_win32_traits(traits) path1 = traits.as_str0(path1) path2 = traits.as_str0(path2) if not win32traits.MoveFileEx(path1, path2, 0): raise rwin32.lastSavedWindowsError() + else: + handle_posix_error('rename', + c_rename(_as_bytes0(path1), _as_bytes0(path2))) @specialize.argtype(0, 1) def replace(path1, path2): From pypy.commits at gmail.com Tue Apr 16 07:39:31 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Tue, 16 Apr 2019 04:39:31 -0700 (PDT) Subject: [pypy-commit] pypy winmultiprocessing: implemented dummy sem_unlink on win32 to match cpython and Message-ID: <5cb5bef3.1c69fb81.21a40.ffb4@mx.google.com> Author: andrewjlawrence Branch: winmultiprocessing Changeset: r96501:733e6283181b Date: 2019-04-16 12:33 +0100 http://bitbucket.org/pypy/pypy/changeset/733e6283181b/ Log: implemented dummy sem_unlink on win32 to match cpython and enable multiprocessing tests diff --git a/pypy/module/_multiprocessing/__init__.py b/pypy/module/_multiprocessing/__init__.py --- a/pypy/module/_multiprocessing/__init__.py +++ b/pypy/module/_multiprocessing/__init__.py @@ -15,5 +15,5 @@ interpleveldefs['closesocket'] = 'interp_win32_py3.multiprocessing_closesocket' interpleveldefs['recv'] = 'interp_win32_py3.multiprocessing_recv' interpleveldefs['send'] = 'interp_win32_py3.multiprocessing_send' - else: - interpleveldefs['sem_unlink'] = 'interp_semaphore.semaphore_unlink' + + interpleveldefs['sem_unlink'] = 'interp_semaphore.semaphore_unlink' diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -36,8 +36,14 @@ save_err=rffi.RFFI_SAVE_LASTERROR) def sem_unlink(name): - pass + return None + def semaphore_unlink(space, w_name): + name = space.text_w(w_name) + try: + sem_unlink(name) + except OSError as e: + raise wrap_oserror(space, e) else: from rpython.rlib import rposix From pypy.commits at gmail.com Tue Apr 16 07:43:25 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 16 Apr 2019 04:43:25 -0700 (PDT) Subject: [pypy-commit] pypy default: tag v7.1.1 releases and remove duplicates in .hgtag Message-ID: <5cb5bfdd.1c69fb81.879d1.e4a7@mx.google.com> Author: Matti Picus Branch: Changeset: r96502:681db379cb89 Date: 2019-04-16 14:39 +0300 http://bitbucket.org/pypy/pypy/changeset/681db379cb89/ Log: tag v7.1.1 releases and remove duplicates in .hgtag diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -6,14 +6,9 @@ ab0dd631c22015ed88e583d9fdd4c43eebf0be21 pypy-2.1-beta1-arm 20e51c4389ed4469b66bb9d6289ce0ecfc82c4b9 release-2.3.0 394146e9bb673514c61f0150ab2013ccf78e8de7 release-2.3 -32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1 32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1 10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0 9c4588d731b7fe0b08669bd732c2b676cb0a8233 release-2.5.1 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0 f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0 @@ -24,17 +19,10 @@ b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2 40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 -40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 d7724c0a5700b895a47de44074cdf5fd659a988f RevDB-pypy2.7-v5.4.1 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0 e90317857d27917bf840caf675832292ee070510 RevDB-pypy2.7-v5.6.1 @@ -45,33 +33,20 @@ 2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1 c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0 a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0 0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0 3f6eaa010fce78cc7973bdc1dfdb95970f08fed2 release-pypy3.5-v5.10.1 ab0b9caf307db6592905a80b8faffd69b39005b8 release-pypy2.7-v6.0.0 fdd60ed87e941677e8ea11acf9f1819466521bf2 release-pypy3.5-v6.0.0 9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 -9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 c8805ee6d7846ca2722b106eeaa2f128c699aba3 release-pypy2.7-v7.0.0 -1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 -bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 -bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 -6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 -6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 -7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 -7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 +784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1 +8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1 + From pypy.commits at gmail.com Tue Apr 16 10:13:49 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:13:49 -0700 (PDT) Subject: [pypy-commit] pyrepl default: make sure to flush stdout/stderr when calling readline()/raw_input(). It helps to mitigates this pytest issue: Message-ID: <5cb5e31d.1c69fb81.2dad8.9b2f@mx.google.com> Author: Antonio Cuni Branch: Changeset: r266:1a94ebdc7c32 Date: 2019-04-16 16:13 +0200 http://bitbucket.org/pypy/pyrepl/changeset/1a94ebdc7c32/ Log: make sure to flush stdout/stderr when calling readline()/raw_input(). It helps to mitigates this pytest issue: https://github.com/pytest-dev/pytest/issues/5134 Prior to this fix, pdb++ failed to display the output when you run it under the conditions described in the issue above. diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -181,11 +181,19 @@ saved_history_length = -1 startup_hook = None config = ReadlineConfig() + stdin = None + stdout = None + stderr = None def __init__(self, f_in=None, f_out=None): self.f_in = f_in if f_in is not None else os.dup(0) self.f_out = f_out if f_out is not None else os.dup(1) + def setup_std_streams(self, stdin, stdout, stderr): + self.stdin = stdin + self.stdout = stdout + self.stderr = stderr + def get_reader(self): if self.reader is None: console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING) @@ -198,7 +206,18 @@ reader = self.get_reader() except _error: return _old_raw_input(prompt) - reader.ps1 = prompt + + # the builtin raw_input calls PyOS_StdioReadline, which flushes + # stdout/stderr before displaying the prompt. Try to mimic this + # behavior: it seems to be the correct thing to do, and moreover it + # mitigates this pytest issue: + # https://github.com/pytest-dev/pytest/issues/5134 + if self.stdout and hasattr(self.stdout, 'flush'): + self.stdout.flush() + if self.stderr and hasattr(self.stderr, 'flush'): + self.stderr.flush() + + reader.ps1 = prompt return reader.readline(startup_hook=self.startup_hook) def multiline_input(self, more_lines, ps1, ps2, returns_unicode=False): @@ -405,6 +424,7 @@ _wrapper.f_in = f_in _wrapper.f_out = f_out + _wrapper.setup_std_streams(sys.stdin, sys.stdout, sys.stderr) if '__pypy__' in sys.builtin_module_names: # PyPy From pypy.commits at gmail.com Tue Apr 16 10:13:47 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:13:47 -0700 (PDT) Subject: [pypy-commit] pyrepl default: update for newer pytest Message-ID: <5cb5e31b.1c69fb81.d390e.438f@mx.google.com> Author: Antonio Cuni Branch: Changeset: r265:f52da1bc7c82 Date: 2019-04-16 16:01 +0200 http://bitbucket.org/pypy/pyrepl/changeset/f52da1bc7c82/ Log: update for newer pytest diff --git a/testing/test_functional.py b/testing/test_functional.py --- a/testing/test_functional.py +++ b/testing/test_functional.py @@ -6,8 +6,8 @@ import pytest import sys - -def pytest_funcarg__child(request): + at pytest.fixture +def child(request): try: pexpect = pytest.importorskip('pexpect') except SyntaxError: From pypy.commits at gmail.com Tue Apr 16 10:13:51 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:13:51 -0700 (PDT) Subject: [pypy-commit] pyrepl default: Added tag v0.8.5 for changeset 1a94ebdc7c32 Message-ID: <5cb5e31f.1c69fb81.aeae8.6cc1@mx.google.com> Author: Antonio Cuni Branch: Changeset: r267:7cdcbf8e4e3f Date: 2019-04-16 16:13 +0200 http://bitbucket.org/pypy/pyrepl/changeset/7cdcbf8e4e3f/ Log: Added tag v0.8.5 for changeset 1a94ebdc7c32 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -2,3 +2,4 @@ 5f47f9f65ff7127668bdeda102e675c23224d321 pyrepl081 61de8bdd14264ab8af5b336be854cb9bfa720542 pyrepl082 62f2256014af7b74b97c00827f1a7789e00dd814 v0.8.4 +1a94ebdc7c32704d2ae7692ebd9183ede84cc69b v0.8.5 From pypy.commits at gmail.com Tue Apr 16 10:14:21 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:14:21 -0700 (PDT) Subject: [pypy-commit] pyrepl default: Added tag v0.8.5 for changeset 7cdcbf8e4e3f Message-ID: <5cb5e33d.1c69fb81.b752a.165d@mx.google.com> Author: Antonio Cuni Branch: Changeset: r268:17f813917dd7 Date: 2019-04-16 16:14 +0200 http://bitbucket.org/pypy/pyrepl/changeset/17f813917dd7/ Log: Added tag v0.8.5 for changeset 7cdcbf8e4e3f diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -3,3 +3,5 @@ 61de8bdd14264ab8af5b336be854cb9bfa720542 pyrepl082 62f2256014af7b74b97c00827f1a7789e00dd814 v0.8.4 1a94ebdc7c32704d2ae7692ebd9183ede84cc69b v0.8.5 +1a94ebdc7c32704d2ae7692ebd9183ede84cc69b v0.8.5 +7cdcbf8e4e3f46d5adc31c8df4e1bc92d67f08c1 v0.8.5 From pypy.commits at gmail.com Tue Apr 16 10:16:13 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:16:13 -0700 (PDT) Subject: [pypy-commit] pyrepl default: Removed tag v0.8.5 Message-ID: <5cb5e3ad.1c69fb81.48f82.5d04@mx.google.com> Author: Antonio Cuni Branch: Changeset: r269:3333d6195425 Date: 2019-04-16 16:14 +0200 http://bitbucket.org/pypy/pyrepl/changeset/3333d6195425/ Log: Removed tag v0.8.5 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -5,3 +5,5 @@ 1a94ebdc7c32704d2ae7692ebd9183ede84cc69b v0.8.5 1a94ebdc7c32704d2ae7692ebd9183ede84cc69b v0.8.5 7cdcbf8e4e3f46d5adc31c8df4e1bc92d67f08c1 v0.8.5 +7cdcbf8e4e3f46d5adc31c8df4e1bc92d67f08c1 v0.8.5 +0000000000000000000000000000000000000000 v0.8.5 From pypy.commits at gmail.com Tue Apr 16 10:16:24 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:16:24 -0700 (PDT) Subject: [pypy-commit] pyrepl default: bump version Message-ID: <5cb5e3b8.1c69fb81.1590.694e@mx.google.com> Author: Antonio Cuni Branch: Changeset: r270:30208d815456 Date: 2019-04-16 16:15 +0200 http://bitbucket.org/pypy/pyrepl/changeset/30208d815456/ Log: bump version diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name="pyrepl", - version="0.8.4", + version="0.9.0", author="Michael Hudson-Doyle", author_email="micahel at gmail.com", maintainer="Ronny Pfannschmidt", From pypy.commits at gmail.com Tue Apr 16 10:16:26 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 16 Apr 2019 07:16:26 -0700 (PDT) Subject: [pypy-commit] pyrepl default: Added tag v0.9.0 for changeset 30208d815456 Message-ID: <5cb5e3ba.1c69fb81.d390e.4487@mx.google.com> Author: Antonio Cuni Branch: Changeset: r271:6e190161f8b1 Date: 2019-04-16 16:15 +0200 http://bitbucket.org/pypy/pyrepl/changeset/6e190161f8b1/ Log: Added tag v0.9.0 for changeset 30208d815456 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -7,3 +7,4 @@ 7cdcbf8e4e3f46d5adc31c8df4e1bc92d67f08c1 v0.8.5 7cdcbf8e4e3f46d5adc31c8df4e1bc92d67f08c1 v0.8.5 0000000000000000000000000000000000000000 v0.8.5 +30208d815456e7ba8b1d0420bdccdb12f0d2f2fd v0.9.0 From pypy.commits at gmail.com Tue Apr 16 10:33:02 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 16 Apr 2019 07:33:02 -0700 (PDT) Subject: [pypy-commit] pypy.org extradoc: update for 7.1.1, regenerate Message-ID: <5cb5e79e.1c69fb81.8623b.f668@mx.google.com> Author: Matti Picus Branch: extradoc Changeset: r946:90eb83066b05 Date: 2019-04-16 17:32 +0300 http://bitbucket.org/pypy/pypy.org/changeset/90eb83066b05/ Log: update for 7.1.1, regenerate diff --git a/contact.html b/contact.html --- a/contact.html +++ b/contact.html @@ -65,7 +65,7 @@
    • irc: #pypy on irc.freenode.net
    • mailing list: pypy-dev at python.org
    • -
    • for security related issues, non-public funding enquiries etc. please contact pypy@sfconservancy.org
    • +
    • for security related issues, non-public funding enquiries etc. please contact pypy-z@python.org
    • the bitbucket bug tracker (registration required to open new issues or to comment)
    • more on our dev site.
    • code on bitbucket.
    • diff --git a/download.html b/download.html --- a/download.html +++ b/download.html @@ -66,7 +66,7 @@ as stable as the release, but they contain numerous bugfixes and performance improvements.

      We provide binaries for x86, ARM, PPC and s390x running on different operating systems such as -Linux, Mac OS X and Windows (what's new in PyPy 7.1?):

      +Linux, Mac OS X and Windows (what's new in PyPy 7.1?):

      • the Python2.7 compatible release — PyPy2.7 v7.1
      • the Python3.5 compatible release — PyPy3.5 v7.0
      • @@ -112,16 +112,16 @@

        Python2.7 compatible PyPy 7.1

        @@ -129,8 +129,8 @@

        Python 3.5.3 compatible PyPy3.5 v7.0.0

        -
        -

        Python 3.6 compatible PyPy3.6 v7.1.0-beta

        +
        +

        Python 3.6 compatible PyPy3.6 v7.1.1-beta

        @@ -391,7 +391,17 @@

        Checksums

        -

        Here are the checksums for each of the downloads of PyPy 7.1.0, 7.0.0 and 6.0.0.

        +

        Here are the checksums for each of the downloads of PyPy 7.1.1, 7.1.0, 7.0.0

        +

        pypy2.7-7.1.1 sha256:

        +
        +41ca390a76ca0d47b8353a0d6a20d5aab5fad8b0bb647b960d8c33e873d18ef5  pypy2.7-v7.1.1-linux32.tar.bz2
        +73b09ef0860eb9ad7997af3030b22909806a273d90786d78420926df53279d66  pypy2.7-v7.1.1-linux64.tar.bz2
        +31a17294dec96c2191885c776b4ee02112957dc874f7ba03e570537a77b78c35  pypy2.7-v7.1.1-osx64.tar.bz2
        +1ef94c3a9c67c2335cee0b21753036b4696ed588b9d54b7b8036a6ae47f7001d  pypy2.7-v7.1.1-s390x.tar.bz2
        +5f06bede6d71dce8dfbfe797aab26c8e35cb990e16b826914652dc093ad74451  pypy2.7-v7.1.1-src.tar.bz2
        +d9b07a2954ad6dbde94feffd848311e2b5169563d33e3e9f17969579b01a4158  pypy2.7-v7.1.1-src.zip
        +9c59226311f216a181e70ee7b5aa4d9665a15d00f24ae02acec9af7d96355f63  pypy2.7-v7.1.1-win32.zip
        +

        pypy2.7-7.1.0 sha256:

         44ec91e8cb01caab289d8763c203f3aaf288d14325a6c42692bd1ac4e870d758  pypy2.7-v7.1.0-linux32.tar.bz2
        @@ -402,6 +412,16 @@
         e60ce30f9947844da43daaa7658adc0c05330681305225954114772f42df06ec  pypy2.7-v7.1.0-src.zip
         76658c9ad679d562b8b6a09d006caa666406337b9834ff56db16980c5e549f20  pypy2.7-v7.1.0-win32.zip
         
        +

        pypy3.6-7.1.1 sha256:

        +
        +cb11ef4b0df569c28390b1ee93029159e1b90bfbad98df6abd629d5203b2abd9  pypy3.6-v7.1.1-linux32.tar.bz2
        +8014f63b1a34b155548852c7bf73aab2d41ebddf2c8fb603dc9dd8509be93db0  pypy3.6-v7.1.1-linux64.tar.bz2
        +a5c2f2bfa2b4a4d29e8a67baab95699b169054066df218a14f171bb84a6df0c0  pypy3.6-v7.1.1-osx64.tar.bz2
        +4a91bf2d9a142b6dbf82b5301cb510535ae9a54e1645546b2e0735a7b5ed85ba  pypy3.6-v7.1.1-s390x.tar.bz2
        +6a3ef876e3691a54f4cff045028ec3be94ab9beb2e99f051b83175302c1899a8  pypy3.6-v7.1.1-src.tar.bz2
        +4a3ebeb767740f2dc0b886d02797d21d7d69f154cf951bb991c19bd485e6cae1  pypy3.6-v7.1.1-src.zip
        +8b513b254de5f31890f5956569de9aec3a0a91d7aba72fc89d66901f4a8ccf49  pypy3.6-v7.1.1-win32.zip
        +

        pypy 3.6-v7.1.0 sha256:

         031bfac61210a6e161bace0691b854dc15d01b0e624dc0588c544ee5e1621a83  pypy3.6-v7.1.0-linux32.tar.bz2
        @@ -436,38 +456,6 @@
         b2ddb0f45cb4e0384fb498ef7fcca2ac96c730b9000affcf8d730169397f017f  pypy3.5-v7.0.0-src.tar.bz2
         3aa3a921c163667761165dbd2070e56d6715979fe9cc1f135d58ea0692a05a1e  pypy3.5-v7.0.0-src.zip
         
        -

        pypy 3.6-v7.0.0-alpha sha256:

        -
        -8576bde0760c239040706cf4952995eb0e77938b175885392a465a0d1616173d  pypy3.6-v7.0.0-linux64.tar.bz2
        -4a95ffd61fd2d626a9c099db6e44889c2a7eecee9cb1cbc29e06603c218ba8e2  pypy3.6-v7.0.0-osx64.tar.bz2
        -645d81472d16922fd592e9261da449cb19847ff7d5eaa89bcf05d9214b6b2698  pypy3.6-v7.0.0-win32.zip
        -7ccbf81db5c647fa0c27636c7d18d059d2570fff7eaffc03857c67bee84b8a26  pypy3.6-v7.0.0-src.tar.bz2
        -867dce40a63caccde161d90a0792e69f2a510a1f3147b694731052be52fafe5c  pypy3.6-v7.0.0-src.zip
        -
        -

        pypy2.7-6.0.0 sha256:

        -
        -ad1082d4328ae8f32617b14628648583b82b6d29df3aa42b97bd1853c08c4bc8  pypy2-v6.0.0-linux32.tar.bz2
        -6cbf942ba7c90f504d8d6a2e45d4244e3bf146c8722d64e9410b85eac6b5af67  pypy2-v6.0.0-linux64.tar.bz2
        -924ca3f90aa28e8961859508c25752c95253b842318a0f267267ffe90f56a916  pypy2-v6.0.0-linux-armel.tar.bz2
        -6506ce739e31981e5596d3cc2e2c7f5b086ee77bb4d97773082b62b2f283eef2  pypy2-v6.0.0-linux-armhf-raspbian.tar.bz2
        -d7dc443e6bb9a45212e8d8f5a63e9f6ce23f1d88c50709efea1c75b76c8bc186  pypy2-v6.0.0-osx64.tar.bz2
        -bf155c8ac2f757d24361591080a9f4f95424a07e30f943f7d751d96442e0f36a  pypy2-v6.0.0-s390x.tar.bz2
        -6097ec5ee23d0d34d8cd27a1072bed041c8a080ad48731190a03a2223029212d  pypy2-v6.0.0-src.tar.bz2
        -3553b19447cdb627919cc37d76979e15dc755b085e979f5ffa9b25933ec343b3  pypy2-v6.0.0-src.zip
        -6e2210dae1ae721ed4eb9cba19f15453514b64111511c84f24843c4fdefdaf7f  pypy2-v6.0.0-win32.zip
        -
        -

        pypy 3.5-v6.0.0 sha256:

        -
        -b04eeee5160e6cb5f8962de80f077ea1dc7be34e77d74bf075519c23603f5ff9  pypy3-v6.0.0-linux32.tar.bz2
        -4cfffa292b9ef34bb6ba39cdbaa196c5c5cbbc5aa3faaa157cf45d7e34027048  pypy3-v6.0.0-linux64.tar.bz2
        -6a6888a55192f58594838b8b3d2e7daaad43d3bf4293afab3dd8987d0bbd1124  pypy3-v6.0.0-linux-armel.tar.bz2
        -8a0420dda23413925400538bbfc0cff2bbb2ab0de984eef6faaeab6d3309cbcc  pypy3-v6.0.0-linux-armhf-raspbian.tar.bz2
        -938b8034e30f5f5060d2a079070c56c3be5559bc7ae9cc0c8395fe6fc45cfe4c  pypy3-v6.0.0-osx64.tar.bz2
        -f0a3097cf74d6b1fb3ae2a060384e72b7868ca76cd04584336b417e9982ec0a5  pypy3-v6.0.0-s390x.tar.bz2
        -ed8005202b46d6fc6831df1d13a4613bc40084bfa42f275068edadf8954034a3  pypy3-v6.0.0-src.tar.bz2
        -8cd3cc2ef362e774edf9c7a6b79dbe42fff75217c5ed96b235a0a792e4421dc4  pypy3-v6.0.0-src.zip
        -72dddb3746a51f7672c77d619c818e27efe899e08ae82762448e50dbfdc2f5f3  pypy3-v6.0.0-win32.zip
        -
        -
        -

        Python2.7 compatible PyPy 7.1

        +
        +

        Python2.7 compatible PyPy 7.1.1

        +
        +

        Python 3.6 compatible PyPy3.6 v7.1.1-beta

        + +

        Python 3.5.3 compatible PyPy3.5 v7.0.0

          @@ -140,19 +153,6 @@
        • All our downloads, including previous versions. We also have a mirror, but please use only if you have troubles accessing the links above
        -
        -
        -

        Python 3.6 compatible PyPy3.6 v7.1.1-beta

        -

        If your CPU is really, really old, it may be a x86-32 without SSE2. There is untested support for manually translating PyPy's JIT without SSE2 (--jit-backend=x86-without-sse2) but note that your machine @@ -276,8 +276,8 @@

        Alternatively, get one of the following smaller packages for the source at the same revision as the above binaries:

      • Make sure you installed the dependencies. See the list here.

        From pypy.commits at gmail.com Wed Apr 17 05:54:57 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 17 Apr 2019 02:54:57 -0700 (PDT) Subject: [pypy-commit] pypy default: Document the newer CPython finalizer behaviour Message-ID: <5cb6f7f1.1c69fb81.be039.9c7b@mx.google.com> Author: Armin Rigo Branch: Changeset: r96511:628b9a8274a2 Date: 2019-04-17 11:54 +0200 http://bitbucket.org/pypy/pypy/changeset/628b9a8274a2/ Log: Document the newer CPython finalizer behaviour diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -88,7 +88,9 @@ There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times -if the object is resurrected and dies again. The ``__del__`` methods are +if the object is resurrected and dies again (at least it is reliably so in +older CPythons; newer CPythons try to call destructors not more than once, +but there are counter-examples). The ``__del__`` methods are called in "the right" order if they are on objects pointing to each other, as in CPython, but unlike CPython, if there is a dead cycle of objects referencing each other, their ``__del__`` methods are called anyway; From pypy.commits at gmail.com Wed Apr 17 06:10:29 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 17 Apr 2019 03:10:29 -0700 (PDT) Subject: [pypy-commit] pypy arm64: (fijal, arigo) ovf ops Message-ID: <5cb6fb95.1c69fb81.63afa.07ea@mx.google.com> Author: fijal Branch: arm64 Changeset: r96512:a6eddad931b2 Date: 2019-04-17 12:09 +0200 http://bitbucket.org/pypy/pypy/changeset/a6eddad931b2/ Log: (fijal, arigo) ovf ops diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -163,6 +163,11 @@ base = 0b11101011000 self.write32((base << 21) | (rm << 16) | (rn << 5) | 0b11111) + def CMP_rr_shifted(self, rn, rm, imm): + base = 0b11101011100 + assert 0 <= imm <= 63 + self.write32((base << 21) | (rm << 16) | (imm << 10) | (rn << 5) | 0b11111) + def CMP_ri(self, rn, imm): base = 0b1111000100 assert 0 <= imm <= 4095 diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -62,10 +62,9 @@ def emit_comp_op_int_mul_ovf(self, op, arglocs): reg1, reg2, res = arglocs + self.mc.SMULH_rr(r.ip0.value, reg1.value, reg2.value) self.mc.MUL_rr(res.value, reg1.value, reg2.value) - xxx # what to do here? - self.mc.SMULH_rr(res.value, reg1.value, reg2.value) - self.mc.CMP_ri(r.ip0.value, 0) + self.mc.CMP_rr_shifted(r.ip0.value, res.value, 63) def emit_op_int_and(self, op, arglocs): l0, l1, res = arglocs diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -485,7 +485,7 @@ self.assembler.dispatch_comparison(prev_op) # result in CC if prev_op.opnum == rop.INT_MUL_OVF: - return self._guard_impl(guard_op), c.GT + return self._guard_impl(guard_op), c.EQ return self._guard_impl(guard_op), c.VC prepare_guard_op_guard_no_overflow = prepare_guard_op_guard_overflow From pypy.commits at gmail.com Wed Apr 17 11:25:53 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 17 Apr 2019 08:25:53 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: inline compile_loop_or_abort() and simplify Message-ID: <5cb74581.1c69fb81.14191.93fb@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96513:bfb1648a41f4 Date: 2019-04-16 21:13 +0100 http://bitbucket.org/pypy/pypy/changeset/bfb1648a41f4/ Log: inline compile_loop_or_abort() and simplify diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2526,6 +2526,14 @@ else: duplicates[box] = None + def cancelled_too_many_times(self): + if self.staticdata.warmrunnerdesc: + memmgr = self.staticdata.warmrunnerdesc.memory_manager + if memmgr: + if self.cancel_count > memmgr.max_unroll_loops: + return True + return False + def reached_loop_header(self, greenboxes, redboxes): self.heapcache.reset() #reset_virtuals=False) #self.heapcache.reset_keep_likely_virtuals() @@ -2585,20 +2593,27 @@ if self.partial_trace: target_token = self.compile_retrace( original_boxes, live_arg_boxes, start) + self.raise_if_successful(live_arg_boxes, target_token) + # creation of the loop was cancelled! + self.cancel_count += 1 + if self.cancelled_too_many_times(): + self.staticdata.log('cancelled too many times!') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) else: target_token = self.compile_loop( original_boxes, live_arg_boxes, start) - self.raise_if_successful(live_arg_boxes, target_token) + self.raise_if_successful(live_arg_boxes, target_token) + # creation of the loop was cancelled! + self.cancel_count += 1 + if self.cancelled_too_many_times(): + target_token = self.compile_loop( + original_boxes, live_arg_boxes, start, + try_disabling_unroll=True) + self.raise_if_successful(live_arg_boxes, target_token) + # + self.staticdata.log('cancelled too many times!') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) self.exported_state = None - # creation of the loop was cancelled! - self.cancel_count += 1 - if self.staticdata.warmrunnerdesc: - memmgr = self.staticdata.warmrunnerdesc.memory_manager - if memmgr: - if self.cancel_count > memmgr.max_unroll_loops: - self.compile_loop_or_abort(original_boxes, - live_arg_boxes, - start) self.staticdata.log('cancelled, tracing more...') # Otherwise, no loop found so far, so continue tracing. @@ -2749,21 +2764,6 @@ target_token.targeting_jitcell_token) return target_token - def compile_loop_or_abort(self, original_boxes, live_arg_boxes, - start): - """Called after we aborted more than 'max_unroll_loops' times. - As a last attempt, try to compile the loop with unrolling disabled. - """ - if not self.partial_trace: - self.history.trace.tracing_done() - target_token = self.compile_loop( - original_boxes, live_arg_boxes, start, - try_disabling_unroll=True) - self.raise_if_successful(live_arg_boxes, target_token) - # - self.staticdata.log('cancelled too many times!') - raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) - def compile_retrace(self, original_boxes, live_arg_boxes, start): num_green_args = self.jitdriver_sd.num_green_args greenkey = original_boxes[:num_green_args] From pypy.commits at gmail.com Thu Apr 18 02:55:46 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Wed, 17 Apr 2019 23:55:46 -0700 (PDT) Subject: [pypy-commit] pypy winmultiprocessing: Work in progress. Message-ID: <5cb81f72.1c69fb81.eb7db.69ee@mx.google.com> Author: andrewjlawrence Branch: winmultiprocessing Changeset: r96514:1140e7fc5df0 Date: 2019-04-18 07:54 +0100 http://bitbucket.org/pypy/pypy/changeset/1140e7fc5df0/ Log: Work in progress. diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -93,6 +93,7 @@ _kernel32.CreateEventW(NULL, True, False, NULL) def __del__(self): + print("Deleting overlapped") # do this somehow else err = _kernel32.GetLastError() bytes = _ffi.new('DWORD[1]') @@ -107,12 +108,14 @@ @property def event(self): + print("Event") xxx return None def GetOverlappedResult(self, wait): + print("Get overlapped result") transferred = _ffi.new('DWORD[1]', [0]) - res = _kernel32.GetOverlappedResult(self.handle, self.overlapped, transferred, wait != 0) + res = _kernel32.GetOverlappedResult(_int2handle(self.handle), self.overlapped, transferred, wait != 0) if res: err = ERROR_SUCCESS else: @@ -128,18 +131,22 @@ if self.completed and self.readbuffer: if transferred != len(self.readbuffer): raise _WinError() + print("Leaving getoverlappedresult") return transferred[0], err def getbuffer(self): + print("getbuffer") xxx return None def cancel(self): + print("cancel") xxx return None def ReadFile(handle, size, overlapped): + print("ReadFile entered") nread = _ffi.new("DWORD*") err = _ffi.new("DWORD*") use_overlapped = overlapped @@ -166,7 +173,7 @@ err = 0 else: err = _kernel32.GetLastError() - + print("Error {0}".format(err)) if overlapped: if not ret: if err == ERROR_IO_PENDING: @@ -182,9 +189,11 @@ return buf, err - +def WriteFile(): + xxx def ConnectNamedPipe(handle, overlapped=False): + print("Connecting named pipe") handle = _int2handle(handle) if overlapped: ov = Overlapped(handle) @@ -211,6 +220,7 @@ def DuplicateHandle(source_process, source, target_process, access, inherit, options=0): # CPython: the first three arguments are expected to be integers + print("DuplicateHandle") target = _ffi.new("HANDLE[1]") res = _kernel32.DuplicateHandle( @@ -221,7 +231,8 @@ if not res: raise _WinError() - + + print("Leaving DuplicateHandle") return _handle2int(target[0]) def _Z(input): @@ -271,16 +282,16 @@ pi.dwThreadId) def OpenProcess(desired_access, inherit_handle, process_id): - + print("OpenProcess") handle = _kernel32.OpenProcess(desired_access, inherit_handle, process_id) - if (handle == _ffi.NULL): + if handle == _ffi.NULL: SetFromWindowsErr(0) handle = INVALID_HANDLE_VALUE - return handle + return _handle2int(handle) def PeekNamedPipe(handle, size=0): - xxx + print("Entering Peek Named Pipe") nread = _ffi.new("DWORD*") navail = _ffi.new("DWORD*") nleft = _ffi.new("DWORD*") @@ -302,6 +313,7 @@ # if (_PyBytes_Resize(&buf, nread)) # return NULL; + print("Leaving print named pipe") return buf, navail, nleft else: ret = _kernel32.PeekNamedPipe(_int2handle(handle), _ffi.NULL, 0, _ffi.NULL, navail, nleft) @@ -309,17 +321,20 @@ # In CPython SetExcFromWindowsErr is called here. # Not sure what that is doing currently. SetFromWindowsErr(0) + print("Leaving print named pipe") return navail, nleft def WaitForSingleObject(handle, milliseconds): + print("Entering waitforsingle object") # CPython: the first argument is expected to be an integer. res = _kernel32.WaitForSingleObject(_int2handle(handle), milliseconds) if res < 0: raise _WinError() - + print("leavng waitforsingle object") return res def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds): + print("Entering waitformultipleobjects") if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS: return None @@ -328,6 +343,7 @@ if res == WAIT_FAILED: raise _WinError() + print("leaving waitformultipleobjects") return int(res) @@ -343,6 +359,7 @@ return code[0] def TerminateProcess(handle, exitcode): + print("Terminating process") # CPython: the first argument is expected to be an integer. # The second argument is silently wrapped in a UINT. res = _kernel32.TerminateProcess(_int2handle(handle), From pypy.commits at gmail.com Thu Apr 18 03:27:17 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 18 Apr 2019 00:27:17 -0700 (PDT) Subject: [pypy-commit] buildbot default: change tannit -> benchmarker Message-ID: <5cb826d5.1c69fb81.1aa88.5366@mx.google.com> Author: Matti Picus Branch: Changeset: r1079:2e976793596a Date: 2019-04-18 10:26 +0300 http://bitbucket.org/pypy/buildbot/changeset/2e976793596a/ Log: change tannit -> benchmarker diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -15,15 +15,15 @@ # to be run on each slave in parallel. However, they assume that each # buildslave is on a differen physical machine, which is not the case for # bencher4 and bencher4_32. As a result, we have to use a global lock, and -# manually tell each builder that uses tannit to acquire it. +# manually tell each builder that uses benchmarker to acquire it. # # Look at the various "locks" session in master.py/BuildmasterConfig. For # benchmarks, the locks is aquired for the single steps: this way we can run # translations in parallel, but then the actual benchmarks are run in # sequence. -# tannit has 8 logical CPUs, but only 4 physical ones, and memory for ~3 translations -TannitCPU = locks.MasterLock('tannit_cpu', maxCount=3) +# benchmarker has 8 logical CPUs, but only 4 physical ones, and memory for ~6 translations +BenchmarkerLock = locks.MasterLock('benchmarker', maxCount=3) SpeedPythonCPU = locks.MasterLock('speed_python_cpu', maxCount=24) WinSlaveLock = locks.SlaveLock('win_cpu', maxCount=1) # speed-old has 24 cores, but memory for ~2 translations @@ -809,7 +809,7 @@ self.addStep(Trigger(schedulerNames=[trigger])) class JITBenchmarkSingleRun(factory.BuildFactory): - def __init__(self, platform='linux', host='tannit', postfix=''): + def __init__(self, platform='linux', host='speed_python', postfix=''): factory.BuildFactory.__init__(self) repourl = 'https://bitbucket.org/pypy/benchmarks' @@ -817,8 +817,8 @@ force_branch='single-run') # setup_steps(platform, self) - if host == 'tannit': - lock = TannitCPU + if host == 'benchmarker': + lock = BenchmarkerLock elif host == 'speed_python': lock = SpeedPythonCPU else: @@ -854,7 +854,7 @@ workdir=".")) class JITBenchmark(factory.BuildFactory): - def __init__(self, platform='linux', host='tannit', postfix=''): + def __init__(self, platform='linux', host='benchmarker', postfix=''): factory.BuildFactory.__init__(self) # @@ -862,8 +862,8 @@ update_hg(platform, self, repourl, 'benchmarks', use_branch=False) # setup_steps(platform, self) - if host == 'tannit': - lock = TannitCPU + if host == 'benchmarker': + lock = BenchmarkerLock elif host == 'speed_python': lock = SpeedPythonCPU else: diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -66,7 +66,7 @@ # all ARM buildbot configuration is in arm_master.py ARM = load('pypybuildbot.arm_master') -TannitCPU = pypybuilds.TannitCPU +BenchmarkerLock = pypybuilds.BenchmarkerLock WinSlaveLock = pypybuilds.WinSlaveLock #SpeedOldLock = pypybuilds.SpeedOldLock Bencher4Lock = pypybuilds.Bencher4Lock @@ -174,9 +174,9 @@ pypyjit=True, app_tests=True) -pypyJITBenchmarkFactory_tannit = pypybuilds.JITBenchmark(host='tannit') -pypyJITBenchmarkFactory64_tannit = pypybuilds.JITBenchmark(platform='linux64', - host='tannit', +pypyJITBenchmarkFactory = pypybuilds.JITBenchmark(host='benchmarker') +pypyJITBenchmarkFactory64 = pypybuilds.JITBenchmark(platform='linux64', + host='benchmarker', postfix='-64') pypyJITBenchmarkFactory64_speed = pypybuilds.JITBenchmarkSingleRun( platform='linux64', @@ -286,7 +286,8 @@ 'schedulers': [ # the benchmarks run on benchmarker and (planned) speed-old.python.org. - # All the other linux tests run on bencher4.soft-dev.org. + # 64 bit linux tests run on bencher4.soft-dev.org. + # 32 bit linux tests run on benchmarker. Nightly("nightly-0-00", [ # linux tests LINUX32OWN, # on benchmarker4_32, uses all cores @@ -322,7 +323,7 @@ ), Nightly("nightly-1-00", [ - #JITBENCH64, # on tannit64, uses 1 core (in part exclusively) + #JITBENCH64, # on benchmarker, uses 1 core (in part exclusively) #JITBENCH64_NEW, # on speed64, uses 1 core (in part exclusively) ], branch=None, hour=5, minute=0, @@ -331,7 +332,7 @@ ), Triggerable("NUMPY64_scheduler", [ - #NUMPY_64, # on tannit64, uses 1 core, takes about 5min. + #NUMPY_64, # uses 1 core, takes about 5min. ]), Triggerable("NUMPYWIN_scheduler", [ @@ -413,14 +414,14 @@ "builddir": LINUX32OWN, "factory": pypyOwnTestFactory, "category": 'linux32', - "locks": [TannitCPU.access('counting')], + "locks": [BenchmarkerLock.access('counting')], }, {"name": LINUX32RPYTHON, "slavenames": ["salsa_32", "benchmarker32"], "builddir": LINUX32RPYTHON, "factory": pypyRPythonTestFactory, "category": 'linux32', - "locks": [TannitCPU.access('counting')], + "locks": [BenchmarkerLock.access('counting')], }, {"name": LINUX64OWN, #"slavenames": ["bencher4", "speed-old"], @@ -444,7 +445,7 @@ "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'linux32', - "locks": [TannitCPU.access('counting')], + "locks": [BenchmarkerLock.access('counting')], }, {"name": APPLVLLINUX64, #"slavenames": ["bencher4", "speed-old"], @@ -460,7 +461,7 @@ "builddir": LIBPYTHON_LINUX32, "factory": pypyTranslatedLibPythonTestFactory, 'category': 'linux32', - "locks": [TannitCPU.access('counting')], + "locks": [BenchmarkerLock.access('counting')], }, {"name": LIBPYTHON_LINUX64, #"slavenames": ["bencher4", "speed-old"], @@ -476,7 +477,7 @@ 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'linux32', - "locks": [TannitCPU.access('counting')], + "locks": [BenchmarkerLock.access('counting')], }, {'name': JITLINUX64, #'slavenames': ["bencher4", "speed-old"], @@ -487,9 +488,9 @@ "locks": [Bencher4Lock.access('counting')], }, {"name": JITBENCH64, - "slavenames": ["tannit64", "benchmarker"], + "slavenames": ["benchmarker"], "builddir": JITBENCH64, - "factory": pypyJITBenchmarkFactory64_tannit, + "factory": pypyJITBenchmarkFactory64, "category": "benchmark-run", # the locks are acquired with fine grain inside the build }, @@ -564,7 +565,7 @@ 'builddir': NUMPY_64, 'factory': pypyNumpyCompatability, 'category': 'numpy', - #'locks': [TannitCPU.access('counting')], + 'locks': [BenchmarkerLock.access('counting')], "locks": [Bencher4Lock.access('counting')], }, {'name': NUMPY_WIN, From pypy.commits at gmail.com Thu Apr 18 03:42:48 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 18 Apr 2019 00:42:48 -0700 (PDT) Subject: [pypy-commit] benchmarks default: minimum changes to save results on newer codespeed, more improvements possible Message-ID: <5cb82a78.1c69fb81.33132.4603@mx.google.com> Author: Matti Picus Branch: Changeset: r379:9a13486fa4c7 Date: 2019-04-18 10:41 +0300 http://bitbucket.org/pypy/benchmarks/changeset/9a13486fa4c7/ Log: minimum changes to save results on newer codespeed, more improvements possible diff --git a/savecpython.py b/savecpython.py --- a/savecpython.py +++ b/savecpython.py @@ -37,21 +37,20 @@ else: print("ERROR: result type unknown " + b[1]) return 1 - data = { + data = [{ 'commitid': revision, 'project': project, 'executable': executable, 'benchmark': bench_name, 'environment': host, 'result_value': value, - 'result_date': current_date, 'branch': 'default', - } + }] if res_type == "ComparisonResult": if base: - data['std_dev'] = results['std_base'] + data[0]['std_dev'] = results['std_base'] else: - data['std_dev'] = results['std_changed'] + data[0]['std_dev'] = results['std_changed'] if testing: testparams.append(data) else: send(data) if testing: return testparams @@ -59,14 +58,14 @@ def send(data): #save results - params = urllib.urlencode(data) + params = urllib.urlencode({'json': json.dumps(data)}) f = None response = "None" - info = str(datetime.today()) + ": Saving result for " + data['executable'] + " revision " - info += str(data['commitid']) + ", benchmark " + data['benchmark'] + info = str(datetime.today()) + ": Saving result for " + data[0]['executable'] + " revision " + info += str(data[0]['commitid']) + ", benchmark " + data[0]['benchmark'] print(info) try: - f = urllib2.urlopen(SPEEDURL + 'result/add/', params) + f = urllib2.urlopen(SPEEDURL + 'result/add/json/', params) response = f.read() f.close() except urllib2.URLError, e: diff --git a/saveresults.py b/saveresults.py --- a/saveresults.py +++ b/saveresults.py @@ -27,6 +27,7 @@ import time import urllib import urllib2 +import json def save(project, revision, results, executeable, host, url, testing=False, @@ -62,7 +63,7 @@ else: print("ERROR: result type unknown " + b[1]) return 1 - data = { + data = [{ 'commitid': revision, 'project': project, 'executable': executeable, @@ -70,15 +71,15 @@ 'environment': host, 'result_value': value, 'branch': branch, - } + }] if value is None: print "Ignoring skipped result", data continue if res_type == "ComparisonResult": if changed: - data['std_dev'] = results['std_changed'] + data[0]['std_dev'] = results['std_changed'] else: - data['std_dev'] = results['std_base'] + data[0]['std_dev'] = results['std_base'] if testing: testparams.append(data) else: @@ -94,19 +95,22 @@ def send(data, url): #save results - params = urllib.urlencode(data) + params = urllib.urlencode({'json': json.dumps(data)}) f = None response = "None" info = ("%s: Saving result for %s revision %s, benchmark %s" % - (str(datetime.today()), data['executable'], - str(data['commitid']), data['benchmark'])) + (str(datetime.today()), data[0]['executable'], + str(data[0]['commitid']), data[0]['benchmark'])) print(info) try: retries = [1, 2, 3, 6] while True: try: - f = urllib2.urlopen(url + 'result/add/', params) + print('result/add') + f = urllib2.urlopen(url + 'result/add/json/', params) + print('urlopen') response = f.read() + print('response') f.close() break except urllib2.URLError: @@ -163,7 +167,7 @@ parser.add_option('-u', '--url', dest='url', default="http://speed.pypy.org/", help=('Url of the codespeed instance ' - '(default: http://speed.pypy.org)')) + '(default: http://speed.pypy.org/)')) parser.format_description = lambda fmt: __doc__ parser.description = __doc__ options, args = parser.parse_args() From pypy.commits at gmail.com Thu Apr 18 05:03:06 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 02:03:06 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix for unicode.translate() Message-ID: <5cb83d4a.1c69fb81.e8e77.ae5c@mx.google.com> Author: Armin Rigo Branch: Changeset: r96515:a229b0127567 Date: 2019-04-18 11:02 +0200 http://bitbucket.org/pypy/pypy/changeset/a229b0127567/ Log: Test and fix for unicode.translate() diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -711,6 +711,7 @@ raises(TypeError, u'hello'.translate) raises(TypeError, u'abababc'.translate, {ord('a'):''}) + raises(TypeError, u'x'.translate, {ord('x'):0x110000}) def test_unicode_from_encoded_object(self): assert unicode('x', 'utf-8') == u'x' @@ -1278,4 +1279,4 @@ assert str(e.value) == 'decoding Unicode is not supported' def test_newlist_utf8_non_ascii(self): - 'ä'.split("\n")[0] # does not crash \ No newline at end of file + 'ä'.split("\n")[0] # does not crash diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -382,7 +382,7 @@ "or unicode") try: builder.append_code(codepoint) - except ValueError: + except rutf8.OutOfRange: raise oefmt(space.w_TypeError, "character mapping must be in range(0x110000)") return self.from_utf8builder(builder) From pypy.commits at gmail.com Thu Apr 18 05:19:58 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 02:19:58 -0700 (PDT) Subject: [pypy-commit] pypy default: fix test Message-ID: <5cb8413e.1c69fb81.48756.56fa@mx.google.com> Author: Armin Rigo Branch: Changeset: r96516:d7c51628e606 Date: 2019-04-18 11:19 +0200 http://bitbucket.org/pypy/pypy/changeset/d7c51628e606/ Log: fix test diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -43,9 +43,9 @@ guard_no_exception(descr=...) i100 = int_lt(i98, 0) guard_true(i100, descr=...) - i102 = call_i(ConstClass(_ll_4_str_eq_slice_char__rpy_stringPtr_Signed_Signed_Char), p55, i83, 1, i89, descr=) + i102 = call_i(ConstClass(_ll_4_str_eq_slice_char__rpy_stringPtr_Signed_Signed_Char), p13, i83, 1, i89, descr=) guard_true(i102, descr=...) - i104 = int_add(i74, 1) + i104 = int_add(i6, 1) --TICK-- jump(..., descr=...) """ % (-sys.maxint-1,)) From pypy.commits at gmail.com Thu Apr 18 05:24:55 2019 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 18 Apr 2019 02:24:55 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: document branch Message-ID: <5cb84267.1c69fb81.614bc.79a2@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96517:c43c94f0fd51 Date: 2019-04-18 10:44 +0200 http://bitbucket.org/pypy/pypy/changeset/c43c94f0fd51/ Log: document branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -16,3 +16,7 @@ .. branch: datetime_api_27 Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` + +.. branch: issue2968 + +Fix segfault in cpyext_tp_new_tupl From pypy.commits at gmail.com Thu Apr 18 05:24:57 2019 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 18 Apr 2019 02:24:57 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix issue #3001: weird codecs can return strange types when using Message-ID: <5cb84269.1c69fb81.28831.5c16@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96518:b4f7c179d353 Date: 2019-04-18 11:24 +0200 http://bitbucket.org/pypy/pypy/changeset/b4f7c179d353/ Log: fix issue #3001: weird codecs can return strange types when using codes.en/decode but not via unicode.encode/bytes.decode diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -575,14 +575,7 @@ if encoding is None: encoding = space.sys.defaultencoding w_encoder = space.getitem(lookup_codec(space, encoding), space.newint(0)) - w_retval = _call_codec(space, w_encoder, w_obj, "encoding", encoding, errors) - if not space.isinstance_w(w_retval, space.w_bytes): - raise oefmt(space.w_TypeError, - "'%s' encoder returned '%T' instead of 'bytes'; " - "use codecs.encode() to encode to arbitrary types", - encoding, - w_retval) - return w_retval + return _call_codec(space, w_encoder, w_obj, "encoding", encoding, errors) @unwrap_spec(errors='text_or_none') def readbuffer_encode(space, w_data, errors='strict'): @@ -604,14 +597,7 @@ if encoding is None: encoding = space.sys.defaultencoding w_decoder = space.getitem(lookup_codec(space, encoding), space.newint(1)) - w_retval = _call_codec(space, w_decoder, w_obj, "decoding", encoding, errors) - if not isinstance(w_retval, W_UnicodeObject): - raise oefmt(space.w_TypeError, - "'%s' decoder returned '%T' instead of 'str'; " - "use codecs.decode() to decode to arbitrary types", - encoding, - w_retval) - return w_retval + return _call_codec(space, w_decoder, w_obj, "decoding", encoding, errors) @unwrap_spec(errors='text') def register_error(space, errors, w_handler): diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -1386,7 +1386,7 @@ "foo\udca5bar") assert ("foo\udca5bar".encode("iso-8859-3", "surrogateescape") == b"foo\xa5bar") - + def test_warn_escape_decode(self): import warnings import codecs @@ -1399,5 +1399,31 @@ assert len(l) == 2 assert isinstance(l[0].message, DeprecationWarning) + def test_invalid_type_errors(self): + # hex is not a text encoding. it works via the codecs functions, but + # not the methods + import codecs + res = codecs.decode(b"aabb", "hex") + assert res == b"\xaa\xbb" + res = codecs.decode(u"aabb", "hex") + assert res == b"\xaa\xbb" + res = codecs.encode(b"\xaa\xbb", "hex") + assert res == b"aabb" + raises(LookupError, u"abc".encode, "hex") + def test_non_text_codec(self): + import _codecs + def search_function(encoding): + def f(input, errors="strict"): + return 52, len(input) + if encoding == 'test.mynontextenc': + return (f, f, None, None) + return None + _codecs.register(search_function) + res = _codecs.encode(u"abc", "test.mynontextenc") + assert res == 52 + res = _codecs.decode(b"abc", "test.mynontextenc") + assert res == 52 + raises(TypeError, u"abc".encode, "test.mynontextenc") + raises(TypeError, b"abc".decode, "test.mynontextenc") diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -1235,7 +1235,14 @@ a.pos, a.pos + 1) assert False, "always raises" return space.newbytes(utf8) - return encode(space, w_obj, encoding, errors) + w_retval = encode(space, w_obj, encoding, errors) + if not space.isinstance_w(w_retval, space.w_bytes): + raise oefmt(space.w_TypeError, + "'%s' encoder returned '%T' instead of 'bytes'; " + "use codecs.encode() to encode to arbitrary types", + encoding, + w_retval) + return w_retval def decode_object(space, w_obj, encoding, errors=None): @@ -1250,7 +1257,14 @@ lgt = unicodehelper.check_utf8_or_raise(space, s) return space.newutf8(s, lgt) from pypy.module._codecs.interp_codecs import decode - return decode(space, w_obj, encoding, errors) + w_retval = decode(space, w_obj, encoding, errors) + if not isinstance(w_retval, W_UnicodeObject): + raise oefmt(space.w_TypeError, + "'%s' decoder returned '%T' instead of 'str'; " + "use codecs.decode() to decode to arbitrary types", + encoding, + w_retval) + return w_retval def unicode_from_object(space, w_obj): if space.is_w(space.type(w_obj), space.w_unicode): From pypy.commits at gmail.com Thu Apr 18 05:38:09 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 02:38:09 -0700 (PDT) Subject: [pypy-commit] pypy default: Don't raise ValueError when comparing arrays with out-of-bound unicodes Message-ID: <5cb84581.1c69fb81.97575.5925@mx.google.com> Author: Armin Rigo Branch: Changeset: r96519:8fde6d376fef Date: 2019-04-18 11:37 +0200 http://bitbucket.org/pypy/pypy/changeset/8fde6d376fef/ Log: Don't raise ValueError when comparing arrays with out-of-bound unicodes diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -74,8 +74,8 @@ lgt = min(arr1.len, arr2.len) for i in range(lgt): arr_eq_driver.jit_merge_point(comp_func=comp_op) - w_elem1 = arr1.w_getitem(space, i) - w_elem2 = arr2.w_getitem(space, i) + w_elem1 = arr1.w_getitem(space, i, integer_instead_of_char=True) + w_elem2 = arr2.w_getitem(space, i, integer_instead_of_char=True) if comp_op == EQ: res = space.eq_w(w_elem1, w_elem2) if not res: @@ -1036,10 +1036,11 @@ else: self.fromsequence(w_iterable) - def w_getitem(self, space, idx): + def w_getitem(self, space, idx, integer_instead_of_char=False): item = self.get_buffer()[idx] keepalive_until_here(self) - if mytype.typecode in 'bBhHil': + if mytype.typecode in 'bBhHil' or ( + integer_instead_of_char and mytype.typecode in 'cu'): item = rffi.cast(lltype.Signed, item) return space.newint(item) if mytype.typecode in 'IL': diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -846,14 +846,21 @@ assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" + def test_array_of_chars_equality(self): + input_bytes = '\x01\x63a\x00!' + a = self.array('c', input_bytes) + b = self.array('c', input_bytes) + b.byteswap() + assert a == b + def test_unicode_outofrange(self): input_unicode = u'\x01\u263a\x00\ufeff' a = self.array('u', input_unicode) b = self.array('u', input_unicode) b.byteswap() assert b[2] == u'\u0000' - raises(ValueError, "b[1]") # doesn't work - e = raises(ValueError, "a != b") # doesn't work + assert a != b + e = raises(ValueError, "b[0]") # doesn't work assert str(e.value) == ( "cannot operate on this array('u') because it contains" " character U+1000000 not in range [U+0000; U+10ffff]" From pypy.commits at gmail.com Thu Apr 18 06:03:54 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 03:03:54 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Fix. The general issue is space.newtext("string") where the Message-ID: <5cb84b8a.1c69fb81.93664.9247@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96520:4a70f02715ab Date: 2019-04-18 12:03 +0200 http://bitbucket.org/pypy/pypy/changeset/4a70f02715ab/ Log: Fix. The general issue is space.newtext("string") where the string might contain some random byte-chars from app-level. diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -958,9 +958,17 @@ unicode_name_handler) if first_escape_error_char is not None: + # Here, 'first_escape_error_char' is a single string character. + # Careful, it might be >= '\x80'. If it is, it would made an + # invalid utf-8 string when pasted directory in it. + if ' ' <= first_escape_error_char < '\x7f': + msg = "invalid escape sequence '\\%s'" % (first_escape_error_char,) + else: + msg = "invalid escape sequence: '\\' followed by %s" % ( + space.text_w(space.repr( + space.newbytes(first_escape_error_char))),) space.warn( - space.newtext("invalid escape sequence '\\%s'" - % str(first_escape_error_char)), + space.newtext(msg), space.w_DeprecationWarning ) return space.newtuple([space.newutf8(result, lgt), space.newint(u_len)]) diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -1394,10 +1394,11 @@ with warnings.catch_warnings(record=True) as l: warnings.simplefilter("always") codecs.unicode_escape_decode(b'\\A') - codecs.unicode_escape_decode(b"\\A") + codecs.unicode_escape_decode(b"\\" + b"\xff") assert len(l) == 2 assert isinstance(l[0].message, DeprecationWarning) + assert isinstance(l[1].message, DeprecationWarning) def test_invalid_type_errors(self): # hex is not a text encoding. it works via the codecs functions, but From pypy.commits at gmail.com Thu Apr 18 06:17:59 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 03:17:59 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Fix for issue #3003 Message-ID: <5cb84ed7.1c69fb81.94cf6.98d6@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96521:76db7b07a3b8 Date: 2019-04-18 12:17 +0200 http://bitbucket.org/pypy/pypy/changeset/76db7b07a3b8/ Log: Fix for issue #3003 diff --git a/lib-python/3/pdb.py b/lib-python/3/pdb.py --- a/lib-python/3/pdb.py +++ b/lib-python/3/pdb.py @@ -341,8 +341,14 @@ def interaction(self, frame, traceback): # Restore the previous signal handler at the Pdb prompt. if Pdb._previous_sigint_handler: - signal.signal(signal.SIGINT, Pdb._previous_sigint_handler) - Pdb._previous_sigint_handler = None + try: + signal.signal(signal.SIGINT, Pdb._previous_sigint_handler) + Pdb._previous_sigint_handler = None + except ValueError: + # ValueError happens when we're in a non-main thread, + # if we already invoked pdb in the same program from the + # main thread. (PyPy fix) + pass if self.setup(frame, traceback): # no interaction desired at this time (happens if .pdbrc contains # a command like "continue") From pypy.commits at gmail.com Thu Apr 18 07:11:55 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 04:11:55 -0700 (PDT) Subject: [pypy-commit] cffi default: Add whatsnews Message-ID: <5cb85b7b.1c69fb81.d60b.bc2a@mx.google.com> Author: Armin Rigo Branch: Changeset: r3262:d350e73b9dfb Date: 2019-04-18 13:10 +0200 http://bitbucket.org/cffi/cffi/changeset/d350e73b9dfb/ Log: Add whatsnews diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst --- a/doc/source/whatsnew.rst +++ b/doc/source/whatsnew.rst @@ -3,6 +3,17 @@ ====================== +v1.12.3 +======= + +* Fix for nested struct types that end in a var-sized array (#405). + +* Add support for using ``U`` and ``L`` characters at the end of integer + constants in ``ffi.cdef()`` (thanks Guillaume). + +* More 3.8 fixes. + + v1.12.2 ======= From pypy.commits at gmail.com Thu Apr 18 07:11:57 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 18 Apr 2019 04:11:57 -0700 (PDT) Subject: [pypy-commit] cffi release-1.12: hg merge default Message-ID: <5cb85b7d.1c69fb81.f653.dcb4@mx.google.com> Author: Armin Rigo Branch: release-1.12 Changeset: r3263:553702112a56 Date: 2019-04-18 13:11 +0200 http://bitbucket.org/cffi/cffi/changeset/553702112a56/ Log: hg merge default diff too long, truncating to 2000 out of 2146 lines diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2,7 +2,7 @@ #include #include "structmember.h" -#define CFFI_VERSION "1.12.2" +#define CFFI_VERSION "1.12.3" #ifdef MS_WIN32 #include @@ -174,7 +174,7 @@ #define CT_IS_BOOL 0x00080000 #define CT_IS_FILE 0x00100000 #define CT_IS_VOID_PTR 0x00200000 -#define CT_WITH_VAR_ARRAY 0x00400000 +#define CT_WITH_VAR_ARRAY 0x00400000 /* with open-ended array, anywhere */ /* unused 0x00800000 */ #define CT_LAZY_FIELD_LIST 0x01000000 #define CT_WITH_PACKED_CHANGE 0x02000000 @@ -1331,6 +1331,29 @@ } static int +add_varsize_length(Py_ssize_t offset, Py_ssize_t itemsize, + Py_ssize_t varsizelength, Py_ssize_t *optvarsize) +{ + /* update '*optvarsize' to account for an array of 'varsizelength' + elements, each of size 'itemsize', that starts at 'offset'. */ + Py_ssize_t size = ADD_WRAPAROUND(offset, + MUL_WRAPAROUND(itemsize, varsizelength)); + if (size < 0 || + ((size - offset) / itemsize) != varsizelength) { + PyErr_SetString(PyExc_OverflowError, + "array size would overflow a Py_ssize_t"); + return -1; + } + if (size > *optvarsize) + *optvarsize = size; + return 0; +} + +static int +convert_struct_from_object(char *data, CTypeDescrObject *ct, PyObject *init, + Py_ssize_t *optvarsize); /* forward */ + +static int convert_vfield_from_object(char *data, CFieldObject *cf, PyObject *value, Py_ssize_t *optvarsize) { @@ -1343,20 +1366,11 @@ if (optvarsize != NULL) { /* in this mode, the only purpose of this function is to compute the real size of the structure from a var-sized C99 array */ - Py_ssize_t size, itemsize; assert(data == NULL); - itemsize = cf->cf_type->ct_itemdescr->ct_size; - size = ADD_WRAPAROUND(cf->cf_offset, - MUL_WRAPAROUND(itemsize, varsizelength)); - if (size < 0 || - ((size - cf->cf_offset) / itemsize) != varsizelength) { - PyErr_SetString(PyExc_OverflowError, - "array size would overflow a Py_ssize_t"); - return -1; - } - if (size > *optvarsize) - *optvarsize = size; - return 0; + return add_varsize_length(cf->cf_offset, + cf->cf_type->ct_itemdescr->ct_size, + varsizelength, + optvarsize); } /* if 'value' was only an integer, get_new_array_length() returns it and convert 'value' to be None. Detect if this was the case, @@ -1365,8 +1379,16 @@ if (value == Py_None) return 0; } - if (optvarsize == NULL) + if (optvarsize == NULL) { return convert_field_from_object(data, cf, value); + } + else if ((cf->cf_type->ct_flags & CT_WITH_VAR_ARRAY) != 0 && + !CData_Check(value)) { + Py_ssize_t subsize = cf->cf_type->ct_size; + if (convert_struct_from_object(NULL, cf->cf_type, value, &subsize) < 0) + return -1; + return add_varsize_length(cf->cf_offset, 1, subsize, optvarsize); + } else return 0; } @@ -2171,7 +2193,10 @@ return PyInt_FromLong(value); } if (cd->c_type->ct_flags & (CT_PRIMITIVE_SIGNED|CT_PRIMITIVE_UNSIGNED)) { - return convert_to_object(cd->c_data, cd->c_type); + PyObject *result = convert_to_object(cd->c_data, cd->c_type); + if (result != NULL && PyBool_Check(result)) + result = PyInt_FromLong(PyInt_AsLong(result)); + return result; } else if (cd->c_type->ct_flags & CT_PRIMITIVE_CHAR) { /*READ(cd->c_data, cd->c_type->ct_size)*/ @@ -4951,6 +4976,19 @@ goto error; } } + else if (ftype->ct_flags & (CT_STRUCT|CT_UNION)) { + if (force_lazy_struct(ftype) < 0) /* for CT_WITH_VAR_ARRAY */ + return NULL; + + /* GCC (or maybe C99) accepts var-sized struct fields that are not + the last field of a larger struct. That's why there is no + check here for "last field": we propagate the flag + CT_WITH_VAR_ARRAY to any struct that contains either an open- + ended array or another struct that recursively contains an + open-ended array. */ + if (ftype->ct_flags & CT_WITH_VAR_ARRAY) + ct->ct_flags |= CT_WITH_VAR_ARRAY; + } if (is_union) boffset = 0; /* reset each field at offset 0 */ @@ -6016,6 +6054,11 @@ #endif if (closure == NULL) { Py_DECREF(infotuple); + PyErr_SetString(PyExc_MemoryError, + "Cannot allocate write+execute memory for ffi.callback(). " + "You might be running on a system that prevents this. " + "For more information, see " + "https://cffi.readthedocs.io/en/latest/using.html#callbacks"); return NULL; } cd = PyObject_GC_New(CDataObject_closure, &CDataOwningGC_Type); diff --git a/c/call_python.c b/c/call_python.c --- a/c/call_python.c +++ b/c/call_python.c @@ -1,10 +1,18 @@ #if PY_VERSION_HEX >= 0x03080000 -# define Py_BUILD_CORE -/* for access to the fields of PyInterpreterState */ -# include "internal/pycore_pystate.h" -# undef Py_BUILD_CORE +# define HAVE_PYINTERPSTATE_GETDICT #endif + +static PyObject *_current_interp_key(void) +{ + PyInterpreterState *interp = PyThreadState_GET()->interp; +#ifdef HAVE_PYINTERPSTATE_GETDICT + return PyInterpreterState_GetDict(interp); /* shared reference */ +#else + return interp->modules; +#endif +} + static PyObject *_get_interpstate_dict(void) { /* Hack around to return a dict that is subinterpreter-local. @@ -14,7 +22,7 @@ */ static PyObject *attr_name = NULL; PyThreadState *tstate; - PyObject *d, *builtins; + PyObject *d, *interpdict; int err; tstate = PyThreadState_GET(); @@ -23,8 +31,13 @@ return NULL; } - builtins = tstate->interp->builtins; - if (builtins == NULL) { + PyInterpreterState *interp = tstate->interp; +#ifdef HAVE_PYINTERPSTATE_GETDICT + interpdict = PyInterpreterState_GetDict(interp); /* shared reference */ +#else + interpdict = interp->builtins; +#endif + if (interpdict == NULL) { /* subinterpreter was cleared already, or is being cleared right now, to a point that is too much for us to continue */ return NULL; @@ -38,13 +51,13 @@ goto error; } - d = PyDict_GetItem(builtins, attr_name); + d = PyDict_GetItem(interpdict, attr_name); if (d == NULL) { d = PyDict_New(); if (d == NULL) goto error; - err = PyDict_SetItem(builtins, attr_name, d); - Py_DECREF(d); /* if successful, there is one ref left in builtins */ + err = PyDict_SetItem(interpdict, attr_name, d); + Py_DECREF(d); /* if successful, there is one ref left in interpdict */ if (err < 0) goto error; } @@ -163,7 +176,7 @@ if (infotuple == NULL) return 3; /* no ffi.def_extern() from this subinterpreter */ - new1 = PyThreadState_GET()->interp->modules; + new1 = _current_interp_key(); Py_INCREF(new1); Py_INCREF(infotuple); old1 = (PyObject *)externpy->reserved1; @@ -252,7 +265,7 @@ } else { PyGILState_STATE state = gil_ensure(); - if (externpy->reserved1 != PyThreadState_GET()->interp->modules) { + if (externpy->reserved1 != _current_interp_key()) { /* Update the (reserved1, reserved2) cache. This will fail if we didn't call @ffi.def_extern() in this particular subinterpreter. */ diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1,4 +1,6 @@ import py +import pytest + def _setup_path(): import os, sys if '__pypy__' in sys.builtin_module_names: @@ -12,7 +14,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): @@ -315,8 +317,10 @@ assert p[0] == 0 p = newp(BPtr, 5000) assert p[0] == 5000 - py.test.raises(IndexError, "p[1]") - py.test.raises(IndexError, "p[-1]") + with pytest.raises(IndexError): + p[1] + with pytest.raises(IndexError): + p[-1] def test_reading_pointer_to_float(): BFloat = new_primitive_type("float") @@ -444,7 +448,8 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "x[0]") + with pytest.raises(TypeError): + x[0] def test_default_str(): BChar = new_primitive_type("char") @@ -537,13 +542,16 @@ assert len(a) == LENGTH for i in range(LENGTH): assert a[i] == 0 - py.test.raises(IndexError, "a[LENGTH]") - py.test.raises(IndexError, "a[-1]") + with pytest.raises(IndexError): + a[LENGTH] + with pytest.raises(IndexError): + a[-1] for i in range(LENGTH): a[i] = i * i + 1 for i in range(LENGTH): assert a[i] == i * i + 1 - e = py.test.raises(IndexError, "a[LENGTH+100] = 500") + with pytest.raises(IndexError) as e: + a[LENGTH+100] = 500 assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value) py.test.raises(TypeError, int, a) @@ -558,10 +566,14 @@ a[i] -= i for i in range(42): assert a[i] == -i - py.test.raises(IndexError, "a[42]") - py.test.raises(IndexError, "a[-1]") - py.test.raises(IndexError, "a[42] = 123") - py.test.raises(IndexError, "a[-1] = 456") + with pytest.raises(IndexError): + a[42] + with pytest.raises(IndexError): + a[-1] + with pytest.raises(IndexError): + a[42] = 123 + with pytest.raises(IndexError): + a[-1] = 456 def test_array_of_unknown_length_instance_with_initializer(): p = new_primitive_type("int") @@ -609,10 +621,14 @@ assert a == (p - 1) BPtr = new_pointer_type(new_primitive_type("short")) q = newp(BPtr, None) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "a - q") - e = py.test.raises(TypeError, "q - a") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + a - q + with pytest.raises(TypeError) as e: + q - a assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'" def test_ptr_sub_unaligned(): @@ -625,8 +641,10 @@ assert b - a == (bi - 1240) // size_of_int() assert a - b == (1240 - bi) // size_of_int() else: - py.test.raises(ValueError, "b - a") - py.test.raises(ValueError, "a - b") + with pytest.raises(ValueError): + b - a + with pytest.raises(ValueError): + a - b def test_cast_primitive_from_cdata(): p = new_primitive_type("int") @@ -777,10 +795,12 @@ BStruct = new_struct_type("struct foo") BStructPtr = new_pointer_type(BStruct) p = cast(BStructPtr, 42) - e = py.test.raises(AttributeError, "p.a1") # opaque + with pytest.raises(AttributeError) as e: + p.a1 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot read fields") - e = py.test.raises(AttributeError, "p.a1 = 10") # opaque + with pytest.raises(AttributeError) as e: + p.a1 = 10 # opaque assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: " "cannot write fields") @@ -792,30 +812,41 @@ s.a2 = 123 assert s.a1 == 0 assert s.a2 == 123 - py.test.raises(OverflowError, "s.a1 = sys.maxsize+1") + with pytest.raises(OverflowError): + s.a1 = sys.maxsize+1 assert s.a1 == 0 - e = py.test.raises(AttributeError, "p.foobar") + with pytest.raises(AttributeError) as e: + p.foobar assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "p.foobar = 42") + with pytest.raises(AttributeError) as e: + p.foobar = 42 assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar") + with pytest.raises(AttributeError) as e: + s.foobar assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" - e = py.test.raises(AttributeError, "s.foobar = 42") + with pytest.raises(AttributeError) as e: + s.foobar = 42 assert str(e.value) == "cdata 'struct foo' has no field 'foobar'" j = cast(BInt, 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int' has no attribute 'foobar'" j = cast(new_pointer_type(BInt), 42) - e = py.test.raises(AttributeError, "j.foobar") + with pytest.raises(AttributeError) as e: + j.foobar assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" - e = py.test.raises(AttributeError, "j.foobar = 42") + with pytest.raises(AttributeError) as e: + j.foobar = 42 assert str(e.value) == "cdata 'int *' has no attribute 'foobar'" pp = newp(new_pointer_type(BStructPtr), p) - e = py.test.raises(AttributeError, "pp.a1") + with pytest.raises(AttributeError) as e: + pp.a1 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" - e = py.test.raises(AttributeError, "pp.a1 = 42") + with pytest.raises(AttributeError) as e: + pp.a1 = 42 assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'" def test_union_instance(): @@ -1636,7 +1667,8 @@ assert ("an integer is required" in msg or # CPython "unsupported operand type for int(): 'NoneType'" in msg or # old PyPys "expected integer, got NoneType object" in msg) # newer PyPys - py.test.raises(TypeError, 'p.a1 = "def"') + with pytest.raises(TypeError): + p.a1 = "def" if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' @@ -1766,14 +1798,17 @@ p.a1 = -1 assert p.a1 == -1 p.a1 = 0 - py.test.raises(OverflowError, "p.a1 = 2") + with pytest.raises(OverflowError): + p.a1 = 2 assert p.a1 == 0 # p.a1 = -1 p.a2 = 3 p.a3 = -4 - py.test.raises(OverflowError, "p.a3 = 4") - e = py.test.raises(OverflowError, "p.a3 = -5") + with pytest.raises(OverflowError): + p.a3 = 4 + with pytest.raises(OverflowError) as e: + p.a3 = -5 assert str(e.value) == ("value -5 outside the range allowed by the " "bit field width: -4 <= x <= 3") assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4 @@ -1782,7 +1817,8 @@ # allows also setting the value "1" (it still gets read back as -1) p.a1 = 1 assert p.a1 == -1 - e = py.test.raises(OverflowError, "p.a1 = -2") + with pytest.raises(OverflowError) as e: + p.a1 = -2 assert str(e.value) == ("value -2 outside the range allowed by the " "bit field width: -1 <= x <= 1") @@ -1842,14 +1878,17 @@ assert string(a[2]) == b"." a[2] = b"12345" assert string(a[2]) == b"12345" - e = py.test.raises(IndexError, 'a[2] = b"123456"') + with pytest.raises(IndexError) as e: + a[2] = b"123456" assert 'char[5]' in str(e.value) assert 'got 6 characters' in str(e.value) def test_add_error(): x = cast(new_primitive_type("int"), 42) - py.test.raises(TypeError, "x + 1") - py.test.raises(TypeError, "x - 1") + with pytest.raises(TypeError): + x + 1 + with pytest.raises(TypeError): + x - 1 def test_void_errors(): py.test.raises(ValueError, alignof, new_void_type()) @@ -2181,8 +2220,10 @@ s = newp(BStructPtr) s.a1 = u+'\x00' assert s.a1 == u+'\x00' - py.test.raises(TypeError, "s.a1 = b'a'") - py.test.raises(TypeError, "s.a1 = bytechr(0xFF)") + with pytest.raises(TypeError): + s.a1 = b'a' + with pytest.raises(TypeError): + s.a1 = bytechr(0xFF) s.a1 = u+'\u1234' assert s.a1 == u+'\u1234' if pyuni4: @@ -2196,7 +2237,8 @@ s.a1 = u+'\ud807\udf44' assert s.a1 == u+'\U00011f44' else: - py.test.raises(TypeError, "s.a1 = u+'\U00012345'") + with pytest.raises(TypeError): + s.a1 = u+'\U00012345' # BWCharArray = new_array_type(BWCharP, None) a = newp(BWCharArray, u+'hello \u1234 world') @@ -2220,7 +2262,8 @@ assert list(a) == expected got = [a[i] for i in range(4)] assert got == expected - py.test.raises(IndexError, 'a[4]') + with pytest.raises(IndexError): + a[4] # w = cast(BWChar, 'a') assert repr(w) == "" % (typename, mandatory_u_prefix) @@ -2352,9 +2395,11 @@ def test_cannot_dereference_void(): BVoidP = new_pointer_type(new_void_type()) p = cast(BVoidP, 123456) - py.test.raises(TypeError, "p[0]") + with pytest.raises(TypeError): + p[0] p = cast(BVoidP, 0) - py.test.raises((TypeError, RuntimeError), "p[0]") + with pytest.raises((TypeError, RuntimeError)): + p[0] def test_iter(): BInt = new_primitive_type("int") @@ -2377,12 +2422,12 @@ assert (q == p) is False assert (q != p) is True if strict_compare: - py.test.raises(TypeError, "p < q") - py.test.raises(TypeError, "p <= q") - py.test.raises(TypeError, "q < p") - py.test.raises(TypeError, "q <= p") - py.test.raises(TypeError, "p > q") - py.test.raises(TypeError, "p >= q") + with pytest.raises(TypeError): p < q + with pytest.raises(TypeError): p <= q + with pytest.raises(TypeError): q < p + with pytest.raises(TypeError): q <= p + with pytest.raises(TypeError): p > q + with pytest.raises(TypeError): p >= q r = cast(BVoidP, p) assert (p < r) is False assert (p <= r) is True @@ -2428,7 +2473,8 @@ try: expected = b"hi there\x00"[i] except IndexError: - py.test.raises(IndexError, "buf[i]") + with pytest.raises(IndexError): + buf[i] else: assert buf[i] == bitem2bchr(expected) # --mb_slice-- @@ -2455,15 +2501,18 @@ try: expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + with pytest.raises(IndexError): + buf[i] = bytechr(i & 0xff) else: buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) - py.test.raises(ValueError, 'buf[:] = b"shorter"') - py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + with pytest.raises(ValueError): + buf[:] = b"shorter" + with pytest.raises(ValueError): + buf[:] = b"this is much too long!" buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" buf[:2] = b"HI" @@ -2537,14 +2586,16 @@ BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) x = newp(BCharP) - py.test.raises(TypeError, "del x[0]") + with pytest.raises(TypeError): + del x[0] def test_bug_delattr(): BLong = new_primitive_type("long") BStruct = new_struct_type("struct foo") complete_struct_or_union(BStruct, [('a1', BLong, -1)]) x = newp(new_pointer_type(BStruct)) - py.test.raises(AttributeError, "del x.a1") + with pytest.raises(AttributeError): + del x.a1 def test_variable_length_struct(): py.test.skip("later") @@ -2562,7 +2613,8 @@ assert sizeof(x) == 6 * size_of_long() x[4] = 123 assert x[4] == 123 - py.test.raises(IndexError, "x[5]") + with pytest.raises(IndexError): + x[5] assert len(x.a2) == 5 # py.test.raises(TypeError, newp, BStructP, [123]) @@ -2814,7 +2866,8 @@ BCharP = new_pointer_type(new_primitive_type("char")) p = newp(BCharP, b'X') q = cast(BBoolP, p) - py.test.raises(ValueError, "q[0]") + with pytest.raises(ValueError): + q[0] py.test.raises(TypeError, newp, BBoolP, b'\x00') assert newp(BBoolP, 0)[0] is False assert newp(BBoolP, 1)[0] is True @@ -3114,8 +3167,10 @@ assert c[1] == 123 assert c[3] == 456 assert d[2] == 456 - py.test.raises(IndexError, "d[3]") - py.test.raises(IndexError, "d[-1]") + with pytest.raises(IndexError): + d[3] + with pytest.raises(IndexError): + d[-1] def test_slice_ptr(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -3133,7 +3188,8 @@ c = newp(BIntArray, 5) c[0:5] assert len(c[5:5]) == 0 - py.test.raises(IndexError, "c[-1:1]") + with pytest.raises(IndexError): + c[-1:1] cp = c + 0 cp[-1:1] @@ -3141,17 +3197,23 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) - e = py.test.raises(IndexError, "c[:5]") + with pytest.raises(IndexError) as e: + c[:5] assert str(e.value) == "slice start must be specified" - e = py.test.raises(IndexError, "c[4:]") + with pytest.raises(IndexError) as e: + c[4:] assert str(e.value) == "slice stop must be specified" - e = py.test.raises(IndexError, "c[1:2:3]") + with pytest.raises(IndexError) as e: + c[1:2:3] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[1:2:1]") + with pytest.raises(IndexError) as e: + c[1:2:1] assert str(e.value) == "slice with step not supported" - e = py.test.raises(IndexError, "c[4:2]") + with pytest.raises(IndexError) as e: + c[4:2] assert str(e.value) == "slice start > stop" - e = py.test.raises(IndexError, "c[6:6]") + with pytest.raises(IndexError) as e: + c[6:6] assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): @@ -3165,9 +3227,11 @@ assert list(c) == [0, 100, 300, 400, 0] cp[-1:1] = iter([500, 600]) assert list(c) == [0, 100, 500, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = [1000]") + with pytest.raises(ValueError): + cp[-1:1] = [1000] assert list(c) == [0, 100, 1000, 600, 0] - py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + with pytest.raises(ValueError): + cp[-1:1] = (700, 800, 900) assert list(c) == [0, 100, 700, 800, 0] def test_setslice_array(): @@ -3427,10 +3491,14 @@ assert sizeof(q[0]) == sizeof(BStruct) # # error cases - py.test.raises(IndexError, "p.y[4]") - py.test.raises(TypeError, "p.y = cast(BIntP, 0)") - py.test.raises(TypeError, "p.y = 15") - py.test.raises(TypeError, "p.y = None") + with pytest.raises(IndexError): + p.y[4] + with pytest.raises(TypeError): + p.y = cast(BIntP, 0) + with pytest.raises(TypeError): + p.y = 15 + with pytest.raises(TypeError): + p.y = None # # accepting this may be specified by the C99 standard, # or a GCC strangeness... @@ -3452,6 +3520,15 @@ assert p.a[1] == 20 assert p.a[2] == 30 assert p.a[3] == 0 + # + # struct of struct of varsized array + BStruct2 = new_struct_type("bar") + complete_struct_or_union(BStruct2, [('head', BInt), + ('tail', BStruct)]) + for i in range(2): # try to detect heap overwrites + p = newp(new_pointer_type(BStruct2), [100, [200, list(range(50))]]) + assert p.tail.y[49] == 49 + def test_struct_array_no_length_explicit_position(): BInt = new_primitive_type("int") @@ -3526,8 +3603,10 @@ p[2:5] = [b"*", b"Z", b"T"] p[1:3] = b"XY" assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"] - py.test.raises(TypeError, "p[1:5] = u+'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = u+'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] # for typename in ["wchar_t", "char16_t", "char32_t"]: BUniChar = new_primitive_type(typename) @@ -3536,8 +3615,10 @@ p[2:5] = [u+"*", u+"Z", u+"T"] p[1:3] = u+"XY" assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"] - py.test.raises(TypeError, "p[1:5] = b'XYZT'") - py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]") + with pytest.raises(TypeError): + p[1:5] = b'XYZT' + with pytest.raises(TypeError): + p[1:5] = [1, 2, 3, 4] def test_void_p_arithmetic(): BVoid = new_void_type() @@ -3548,10 +3629,14 @@ assert int(cast(BInt, p - (-42))) == 100042 assert (p + 42) - p == 42 q = cast(new_pointer_type(new_primitive_type("char")), 100000) - py.test.raises(TypeError, "p - q") - py.test.raises(TypeError, "q - p") - py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)") - py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)") + with pytest.raises(TypeError): + p - q + with pytest.raises(TypeError): + q - p + with pytest.raises(TypeError): + p + cast(new_primitive_type('int'), 42) + with pytest.raises(TypeError): + p - cast(new_primitive_type('int'), 42) def test_sizeof_sliced_array(): BInt = new_primitive_type("int") @@ -3766,8 +3851,10 @@ assert p1[0] == lst[0] assert p1[1] == lst[1] assert p1[2] == lst[2] - py.test.raises(IndexError, "p1[3]") - py.test.raises(IndexError, "p1[-1]") + with pytest.raises(IndexError): + p1[3] + with pytest.raises(IndexError): + p1[-1] # py.test.raises(TypeError, from_buffer, BInt, bytestring) py.test.raises(TypeError, from_buffer, BIntP, bytestring) @@ -3778,8 +3865,10 @@ assert len(p2) == 2 assert p2[0] == lst[0] assert p2[1] == lst[1] - py.test.raises(IndexError, "p2[2]") - py.test.raises(IndexError, "p2[-1]") + with pytest.raises(IndexError): + p2[2] + with pytest.raises(IndexError): + p2[-1] assert p2 == p1 # BIntA4 = new_array_type(BIntP, 4) # int[4]: too big @@ -3795,7 +3884,8 @@ assert typeof(p1) is BStructA assert p1[0].a1 == lst[0] assert p1[0].a2 == lst[1] - py.test.raises(IndexError, "p1[1]") + with pytest.raises(IndexError): + p1[1] # BEmptyStruct = new_struct_type("empty") complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) @@ -3887,10 +3977,14 @@ BInt = new_primitive_type("int") BIntPtr = new_pointer_type(BInt) p = cast(BIntPtr, 0) - py.test.raises(RuntimeError, "p[0]") - py.test.raises(RuntimeError, "p[0] = 42") - py.test.raises(RuntimeError, "p[42]") - py.test.raises(RuntimeError, "p[42] = -1") + with pytest.raises(RuntimeError): + p[0] + with pytest.raises(RuntimeError): + p[0] = 42 + with pytest.raises(RuntimeError): + p[42] + with pytest.raises(RuntimeError): + p[42] = -1 def test_mixup(): BStruct1 = new_struct_type("foo") @@ -3906,10 +4000,12 @@ pp2 = newp(BStruct2PtrPtr) pp3 = newp(BStruct3PtrPtr) pp1[0] = pp1[0] - e = py.test.raises(TypeError, "pp3[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp3[0] = pp1[0] assert str(e.value).startswith("initializer for ctype 'bar *' must be a ") assert str(e.value).endswith(", not cdata 'foo *'") - e = py.test.raises(TypeError, "pp2[0] = pp1[0]") + with pytest.raises(TypeError) as e: + pp2[0] = pp1[0] assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to " "be 'foo *', but the types are different (check " "that you are not e.g. mixing up different ffi " @@ -4098,14 +4194,14 @@ assert (a != b) is True assert (b != a) is True if strict_compare: - py.test.raises(TypeError, "a < b") - py.test.raises(TypeError, "a <= b") - py.test.raises(TypeError, "a > b") - py.test.raises(TypeError, "a >= b") - py.test.raises(TypeError, "b < a") - py.test.raises(TypeError, "b <= a") - py.test.raises(TypeError, "b > a") - py.test.raises(TypeError, "b >= a") + with pytest.raises(TypeError): a < b + with pytest.raises(TypeError): a <= b + with pytest.raises(TypeError): a > b + with pytest.raises(TypeError): a >= b + with pytest.raises(TypeError): b < a + with pytest.raises(TypeError): b <= a + with pytest.raises(TypeError): b > a + with pytest.raises(TypeError): b >= a elif a < b: assert_lt(a, b) else: @@ -4151,7 +4247,8 @@ BIntP = new_pointer_type(new_primitive_type("int")) p = newp(BIntP) p[0] = 42 - py.test.raises(IndexError, "p[1]") + with pytest.raises(IndexError): + p[1] release(p) # here, reading p[0] might give garbage or segfault... release(p) # no effect @@ -4187,8 +4284,12 @@ def test_explicit_release_badtype_contextmgr(): BIntP = new_pointer_type(new_primitive_type("int")) p = cast(BIntP, 12345) - py.test.raises(ValueError, "with p: pass") - py.test.raises(ValueError, "with p: pass") + with pytest.raises(ValueError): + with p: + pass + with pytest.raises(ValueError): + with p: + pass def test_explicit_release_gc(): BIntP = new_pointer_type(new_primitive_type("int")) @@ -4248,9 +4349,21 @@ BCharA = new_array_type(BCharP, None) a += b't' * 10 p = from_buffer(BCharA, a) - py.test.raises(BufferError, "a += b'u' * 100") + with pytest.raises(BufferError): + a += b'u' * 100 release(p) a += b'v' * 100 release(p) # no effect a += b'w' * 1000 assert a == bytearray(b"xyz" + b't' * 10 + b'v' * 100 + b'w' * 1000) + +def test_int_doesnt_give_bool(): + BBool = new_primitive_type("_Bool") + x = int(cast(BBool, 42)) + assert type(x) is int and x == 1 + x = long(cast(BBool, 42)) + assert type(x) is long and x == 1 + with pytest.raises(TypeError): + float(cast(BBool, 42)) + with pytest.raises(TypeError): + complex(cast(BBool, 42)) diff --git a/cffi/__init__.py b/cffi/__init__.py --- a/cffi/__init__.py +++ b/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.2" -__version_info__ = (1, 12, 2) +__version__ = "1.12.3" +__version_info__ = (1, 12, 3) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -221,7 +223,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.2" + "\ncompiled with cffi version: 1.12.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -817,12 +817,20 @@ # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - return int(s, 16) - return int(s, 8) - elif '1' <= s[0] <= '9': - return int(s, 10) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif s[0] == "'" and s[-1] == "'" and ( len(s) == 3 or (len(s) == 4 and s[1] == "\\")): return ord(s[-2]) diff --git a/doc/source/conf.py b/doc/source/conf.py --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -47,7 +47,7 @@ # The short X.Y version. version = '1.12' # The full version, including alpha/beta/rc tags. -release = '1.12.2' +release = '1.12.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/installation.rst b/doc/source/installation.rst --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -52,13 +52,13 @@ * https://pypi.python.org/pypi/cffi -* Checksums of the "source" package version 1.12.2: +* Checksums of the "source" package version 1.12.3: - - MD5: 4d7dcb6c7c738c15d2ece9bd4c5f86da + - MD5: ... - - SHA: 5f579d4980cbcc8aac592721f714ef6a64370ab1 + - SHA: ... - - SHA256: e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7 + - SHA256: ... * Or grab the most current version from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` diff --git a/doc/source/using.rst b/doc/source/using.rst --- a/doc/source/using.rst +++ b/doc/source/using.rst @@ -876,11 +876,27 @@ protections can interfere (for example, on SELinux you need to run with ``deny_execmem`` set to ``off``). - Note also that a cffi fix for the latter issue was attempted---see + - `On Mac OS X,`__ you need to give your application the entitlement + ``com.apple.security.cs.allow-unsigned-executable-memory``. + + Note also that a cffi fix for this issue was attempted---see the ``ffi_closure_alloc`` branch---but was not merged because it creates potential `memory corruption`__ with ``fork()``. + In other words: yes, it is dangerous to allow write+execute memory in your + program; that's why the various "hardening" options above exist. But at + the same time, these options open wide the door to another attack: if the + program forks and then attempts to call any of the ``ffi.callback()``, then + this immediately results in a crash---or, with a minimal amount of work + from an attacker, arbitrary code execution. To me it sounds even more + dangerous than the original problem, and that's why cffi is not playing + along. + + To fix the issue once and for all on the affected platforms, you need + to refactor the involved code so that it no longer uses ``ffi.callback()``. + .. __: https://github.com/pyca/pyopenssl/issues/596 +.. __: https://bitbucket.org/cffi/cffi/issues/391/ .. __: https://bugzilla.redhat.com/show_bug.cgi?id=1249685 Warning: like ffi.new(), ffi.callback() returns a cdata that has diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst --- a/doc/source/whatsnew.rst +++ b/doc/source/whatsnew.rst @@ -3,6 +3,17 @@ ====================== +v1.12.3 +======= + +* Fix for nested struct types that end in a var-sized array (#405). + +* Add support for using ``U`` and ``L`` characters at the end of integer + constants in ``ffi.cdef()`` (thanks Guillaume). + +* More 3.8 fixes. + + v1.12.2 ======= diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -198,7 +198,7 @@ `Mailing list `_ """, - version='1.12.2', + version='1.12.3', packages=['cffi'] if cpython else [], package_data={'cffi': ['_cffi_include.h', 'parse_c_type.h', '_embedding.h', '_cffi_errors.h']} diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py --- a/testing/cffi0/backend_tests.py +++ b/testing/cffi0/backend_tests.py @@ -1,4 +1,5 @@ import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -112,10 +113,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -140,18 +145,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -259,7 +267,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -386,7 +395,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -422,13 +432,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -450,8 +462,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -511,11 +525,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -591,7 +607,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -615,7 +632,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -633,7 +651,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -657,18 +676,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -687,7 +709,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -912,10 +935,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -950,11 +977,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1011,17 +1041,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1279,7 +1315,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/testing/cffi0/test_ffi_backend.py b/testing/cffi0/test_ffi_backend.py --- a/testing/cffi0/test_ffi_backend.py +++ b/testing/cffi0/test_ffi_backend.py @@ -129,6 +129,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -268,12 +298,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/testing/cffi0/test_function.py b/testing/cffi0/test_function.py --- a/testing/cffi0/test_function.py +++ b/testing/cffi0/test_function.py @@ -1,4 +1,5 @@ import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -90,7 +91,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -466,3 +466,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -1,4 +1,5 @@ import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from testing.support import * @@ -20,7 +21,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -589,7 +591,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -647,7 +650,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1463,8 +1467,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1532,7 +1538,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2098,6 +2105,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/testing/cffi1/test_ffi_obj.py b/testing/cffi1/test_ffi_obj.py --- a/testing/cffi1/test_ffi_obj.py +++ b/testing/cffi1/test_ffi_obj.py @@ -1,4 +1,5 @@ import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -85,9 +86,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py --- a/testing/cffi1/test_new_ffi_1.py +++ b/testing/cffi1/test_new_ffi_1.py @@ -1,4 +1,5 @@ import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -186,10 +187,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -212,18 +217,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -324,7 +332,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -445,7 +454,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -478,13 +488,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -502,8 +514,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -555,11 +569,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -625,7 +641,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -648,7 +665,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -664,7 +682,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -685,17 +704,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -713,7 +735,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -922,10 +945,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -947,11 +974,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1000,17 +1030,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1235,7 +1271,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1752,7 +1789,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == 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 @@ -1,5 +1,6 @@ import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from testing.udir import udir @@ -188,20 +189,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -247,7 +254,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -263,7 +271,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -315,8 +324,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -387,8 +398,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -398,8 +411,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1020,8 +1035,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] From pypy.commits at gmail.com Thu Apr 18 09:14:20 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 18 Apr 2019 06:14:20 -0700 (PDT) Subject: [pypy-commit] benchmarks default: use https for upload Message-ID: <5cb8782c.1c69fb81.f6c2.221c@mx.google.com> Author: Matti Picus Branch: Changeset: r380:2a200b714bc6 Date: 2019-04-18 16:13 +0300 http://bitbucket.org/pypy/benchmarks/changeset/2a200b714bc6/ Log: use https for upload diff --git a/runner.py b/runner.py --- a/runner.py +++ b/runner.py @@ -196,9 +196,9 @@ help=("Upload results to speed.pypy.org (unless " "--upload-url is given).")) upload_group.add_option( - "--upload-urls", default="http://speed.pypy.org/", + "--upload-urls", default="https://speed.pypy.org/", help=("Comma seperated urls of the codespeed instances " - "to upload to. (default: http://speed.pypy.org/)")) + "to upload to. (default: https://speed.pypy.org/)")) upload_group.add_option( "--upload-project", default="PyPy", help="The project name in codespeed. (default: PyPy)") @@ -227,9 +227,9 @@ "--upload-baseline-url is given).")) upload_baseline_group.add_option( "--upload-baseline-urls", - default="http://speed.pypy.org/", + default="https://speed.pypy.org/", help=("Comma seperated urls of the codespeed instances " - "to upload to. (default: http://speed.pypy.org/)")) + "to upload to. (default: https://speed.pypy.org/)")) upload_baseline_group.add_option( "--upload-baseline-project", default="PyPy", help="The project name in codespeed (default: PyPy).") diff --git a/savecpython.py b/savecpython.py --- a/savecpython.py +++ b/savecpython.py @@ -7,7 +7,7 @@ import optparse #SPEEDURL = 'http://127.0.0.1:8000/' -SPEEDURL = 'http://speed.pypy.org/' +SPEEDURL = 'https://speed.pypy.org/' def save(project, revision, results, options, executable, host, testing=False, base=False): diff --git a/saveresults.py b/saveresults.py --- a/saveresults.py +++ b/saveresults.py @@ -165,9 +165,9 @@ help='upload the results as baseline instead of changed') parser.add_option('-P', '--project', dest='project', default='PyPy') parser.add_option('-u', '--url', dest='url', - default="http://speed.pypy.org/", + default="https://speed.pypy.org/", help=('Url of the codespeed instance ' - '(default: http://speed.pypy.org/)')) + '(default: https://speed.pypy.org/)')) parser.format_description = lambda fmt: __doc__ parser.description = __doc__ options, args = parser.parse_args() From pypy.commits at gmail.com Thu Apr 18 15:05:29 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 18 Apr 2019 12:05:29 -0700 (PDT) Subject: [pypy-commit] buildbot default: use fixed version of benchmark repo, forcing 'branch' or 'revision' refer to pypy Message-ID: <5cb8ca79.1c69fb81.d06a7.b904@mx.google.com> Author: Matti Picus Branch: Changeset: r1080:fc95257ff7ab Date: 2019-04-18 22:05 +0300 http://bitbucket.org/pypy/buildbot/changeset/fc95257ff7ab/ Log: use fixed version of benchmark repo, forcing 'branch' or 'revision' refer to pypy Also use https:/speed.pypy.org url for upload diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -293,7 +293,7 @@ Mercurial._pullUpdate = _my_pullUpdate -def update_hg_old_method(platform, factory, repourl, workdir): +def update_hg_old_method(platform, factory, repourl, workdir, revision): # baaaaaah. Seems that the Mercurial class doesn't support # updating to a different branch than the one specified by # the user (like "default"). This is nonsense if we need @@ -330,14 +330,14 @@ # # here, update without caring about branches factory.addStep(ShellCmd(description="hg update", - command=WithProperties("hg update --clean %(revision)s"), + command="hg update --clean %s" % revision, workdir=workdir)) -def update_hg(platform, factory, repourl, workdir, use_branch, +def update_hg(platform, factory, repourl, workdir, use_branch, revision, force_branch=None, wipe_bookmarks=False): if not use_branch: assert force_branch is None - update_hg_old_method(platform, factory, repourl, workdir) + update_hg_old_method(platform, factory, repourl, workdir, revision) return if wipe_bookmarks: @@ -389,7 +389,8 @@ factory.addStep(ParseRevision(hideStepIf=ParseRevision.hideStepIf, doStepIf=ParseRevision.doStepIf)) # - update_hg(platform, factory, repourl, workdir, use_branch=True, + revision=WithProperties("%(revision)s") + update_hg(platform, factory, repourl, workdir, revision, use_branch=True, force_branch=force_branch, wipe_bookmarks=True) # factory.addStep(CheckGotRevision(workdir=workdir)) @@ -812,8 +813,11 @@ def __init__(self, platform='linux', host='speed_python', postfix=''): factory.BuildFactory.__init__(self) + # Always use the latest version on the single-run branch of the + # benchmark repo, + # branch and revision refer to the pypy version to benchmark repourl = 'https://bitbucket.org/pypy/benchmarks' - update_hg(platform, self, repourl, 'benchmarks', use_branch=True, + update_hg(platform, self, repourl, 'benchmarks', '', use_branch=True, force_branch='single-run') # setup_steps(platform, self) @@ -859,7 +863,9 @@ # repourl = 'https://bitbucket.org/pypy/benchmarks' - update_hg(platform, self, repourl, 'benchmarks', use_branch=False) + # Always use the latest version on the benchmark repo, + # branch and revision refer to the pypy version to benchmark + update_hg(platform, self, repourl, 'benchmarks', 'default', use_branch=False) # setup_steps(platform, self) if host == 'benchmarker': @@ -893,14 +899,14 @@ '--upload-project', 'PyPy', '--revision', WithProperties('%(got_revision)s'), '--branch', WithProperties('%(branch)s'), - '--upload-urls', 'http://speed.pypy.org/', + '--upload-urls', 'https://speed.pypy.org/', '--upload-baseline', '--upload-baseline-executable', 'pypy-c-jit' + postfix, '--upload-baseline-project', 'PyPy', '--upload-baseline-revision', WithProperties('%(got_revision)s'), '--upload-baseline-branch', WithProperties('%(branch)s'), - '--upload-baseline-urls', 'http://speed.pypy.org/', + '--upload-baseline-urls', 'https://speed.pypy.org/', ], workdir='./benchmarks', timeout=3600)) @@ -927,7 +933,7 @@ # check out and update benchmarks repourl = 'https://bitbucket.org/pypy/benchmarks' - update_hg(platform, self, repourl, 'benchmarks', use_branch=False) + update_hg(platform, self, repourl, 'benchmarks', 'default', use_branch=False) # checks out and updates the repo setup_steps(platform, self, repourl='http://hg.python.org/cpython', From pypy.commits at gmail.com Thu Apr 18 15:13:54 2019 From: pypy.commits at gmail.com (mattip) Date: Thu, 18 Apr 2019 12:13:54 -0700 (PDT) Subject: [pypy-commit] buildbot default: fix argument order Message-ID: <5cb8cc72.1c69fb81.80ed.2942@mx.google.com> Author: Matti Picus Branch: Changeset: r1081:f4e9749d24ba Date: 2019-04-18 22:13 +0300 http://bitbucket.org/pypy/buildbot/changeset/f4e9749d24ba/ Log: fix argument order diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -333,7 +333,7 @@ command="hg update --clean %s" % revision, workdir=workdir)) -def update_hg(platform, factory, repourl, workdir, use_branch, revision, +def update_hg(platform, factory, repourl, workdir, revision, use_branch, force_branch=None, wipe_bookmarks=False): if not use_branch: assert force_branch is None From pypy.commits at gmail.com Fri Apr 19 03:37:27 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 00:37:27 -0700 (PDT) Subject: [pypy-commit] pypy.org extradoc: add ppc binaries for 7.1.1 Message-ID: <5cb97ab7.1c69fb81.42e41.09ac@mx.google.com> Author: Armin Rigo Branch: extradoc Changeset: r950:d6e73e3ff15d Date: 2019-04-18 15:03 +0200 http://bitbucket.org/pypy/pypy.org/changeset/d6e73e3ff15d/ Log: add ppc binaries for 7.1.1 diff --git a/download.html b/download.html --- a/download.html +++ b/download.html @@ -118,8 +118,8 @@
      • FreeBSD x86 and x86_64: see FreshPorts
      • Windows binary (32bit) (you might need the VS 2008 runtime library installer vcredist_x86.exe.)
      • -
      • PowerPC PPC64 Linux binary (64bit big-endian, Fedora 20) (see [1] below)
      • -
      • PowerPC PPC64le Linux binary (64bit little-endian, Fedora 21) (see [1] below)
      • +
      • PowerPC PPC64 Linux binary (64bit big-endian, Fedora 20) (see [1] below)
      • +
      • PowerPC PPC64le Linux binary (64bit little-endian, Fedora 21) (see [1] below)
      • s390x Linux binary (built on Redhat Linux 7.2) (see [1] below)
      • Source (tar.bz2); Source (zip). See below for more about the sources.
      • All our downloads, including previous versions. We also have a @@ -133,6 +133,8 @@
      • Linux x86 binary (32bit, built on Ubuntu 14.04) (see [1] below)
      • Mac OS X binary (64bit) (High Sierra >= 10.13, not for Sierra and below)
      • Windows binary (32bit)
      • +
      • PowerPC PPC64 Linux binary (64bit big-endian, Fedora 20) (see [1] below)
      • +
      • PowerPC PPC64le Linux binary (64bit little-endian, Fedora 21) (see [1] below)
      • s390x Linux binary (built on Redhat Linux 7.2) (see [1] below)
      • Source (tar.bz2); Source (zip). See below for more about the sources.
      • All our downloads, including previous versions. We also have a diff --git a/source/download.txt b/source/download.txt --- a/source/download.txt +++ b/source/download.txt @@ -102,8 +102,8 @@ .. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-linux64.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-osx64.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-win32.zip -.. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.0-ppc64.tar.bz2 -.. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.0-ppc64le.tar.bz2 +.. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-ppc64.tar.bz2 +.. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-ppc64le.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-s390x.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-src.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy2.7-v7.1.1-src.zip @@ -122,6 +122,8 @@ * `Linux x86 binary (32bit, built on Ubuntu 14.04)`__ (see ``[1]`` below) * `Mac OS X binary (64bit)`__ (High Sierra >= 10.13, not for Sierra and below) * `Windows binary (32bit)`__ +* `PowerPC PPC64 Linux binary (64bit big-endian, Fedora 20)`__ (see ``[1]`` below) +* `PowerPC PPC64le Linux binary (64bit little-endian, Fedora 21)`__ (see ``[1]`` below) * `s390x Linux binary (built on Redhat Linux 7.2)`__ (see ``[1]`` below) * `Source (tar.bz2)`__; `Source (zip)`__. See below for more about the sources. * `All our downloads,`__ including previous versions. We also have a @@ -131,6 +133,8 @@ .. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-linux32.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-osx64.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-win32.zip +.. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-ppc64.tar.bz2 +.. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-ppc64le.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-s390x.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-src.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.1.1-src.zip From pypy.commits at gmail.com Fri Apr 19 08:25:59 2019 From: pypy.commits at gmail.com (mattip) Date: Fri, 19 Apr 2019 05:25:59 -0700 (PDT) Subject: [pypy-commit] buildbot default: tweak layout, add nightly benchmark runs, try to enable py3.6 run only on changes Message-ID: <5cb9be57.1c69fb81.1d8a.326c@mx.google.com> Author: Matti Picus Branch: Changeset: r1082:d9f4120168a1 Date: 2019-04-19 15:25 +0300 http://bitbucket.org/pypy/buildbot/changeset/d9f4120168a1/ Log: tweak layout, add nightly benchmark runs, try to enable py3.6 run only on changes diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -323,10 +323,10 @@ ), Nightly("nightly-1-00", [ - #JITBENCH64, # on benchmarker, uses 1 core (in part exclusively) + JITBENCH64, # on benchmarker, uses 1 core (in part exclusively) #JITBENCH64_NEW, # on speed64, uses 1 core (in part exclusively) - ], branch=None, hour=5, minute=0, + ], branch=None, hour=7, minute=0, # XXX causes hg updatee -r nnn from pypy/pypy instead of pypy/benchmarks #onlyIfChanged=True, ), @@ -342,7 +342,7 @@ #Nightly("nightly-3-01-py3.5", [LINUX64, JITLINUX64,], # branch="py3.5", hour=3, minute=0), - Nightly("nightly-3-00-py3.5", [ + Nightly("nightly-3-00-py3.6", [ LINUX32OWN, # on bencher4_32, uses all cores JITLINUX32, # on bencher4_32, uses 1 core LINUX64OWN, # on bencher4, uses all cores @@ -350,7 +350,7 @@ JITMACOSX64, # on xerxes JITWIN32, # on SalsaSalsa ], branch="py3.6", hour=3, minute=0, - #onlyIfChanged=True, + onlyIfChanged=True, ), # this one has faithfully run every night even though the latest diff --git a/bot2/pypybuildbot/pypylist.py b/bot2/pypybuildbot/pypylist.py --- a/bot2/pypybuildbot/pypylist.py +++ b/bot2/pypybuildbot/pypylist.py @@ -28,8 +28,8 @@ 'linux': 100, 'linux64': 50, 'osx': 30, - 's390x': 20, - 'win32': 10, + 'win32': 20, + 's390x': 10, 'linux_armhf_raspbian': 7, 'linux_armhf_raring': 6, 'linux_armel': 5, diff --git a/master/templates/layout.html b/master/templates/layout.html --- a/master/templates/layout.html +++ b/master/templates/layout.html @@ -27,7 +27,6 @@ - Speed - - Summary (trunk) - - Summary (py3.5) - Summary (py3.6) - Summary - RPython From pypy.commits at gmail.com Fri Apr 19 11:44:21 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 08:44:21 -0700 (PDT) Subject: [pypy-commit] cffi release-1.12: Windows fix Message-ID: <5cb9ecd5.1c69fb81.bc3d5.4c61@mx.google.com> Author: Armin Rigo Branch: release-1.12 Changeset: r3265:4f23de94bc49 Date: 2019-04-19 17:44 +0200 http://bitbucket.org/cffi/cffi/changeset/4f23de94bc49/ Log: Windows fix diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -145,6 +145,7 @@ int result; PyGILState_STATE state; PyObject *pycode=NULL, *global_dict=NULL, *x; + PyObject *builtins; state = PyGILState_Ensure(); @@ -169,7 +170,7 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - PyObject *builtins = PyEval_GetBuiltins(); + builtins = PyEval_GetBuiltins(); if (builtins == NULL) goto error; if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py --- a/testing/embedding/test_basic.py +++ b/testing/embedding/test_basic.py @@ -63,8 +63,8 @@ output = popen.stdout.read() err = popen.wait() if err: - raise OSError("popen failed with exit code %r: %r" % ( - err, args)) + raise OSError(("popen failed with exit code %r: %r\n\n%s" % ( + err, args, output)).rstrip()) print(output.rstrip()) return output From pypy.commits at gmail.com Fri Apr 19 11:55:44 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 08:55:44 -0700 (PDT) Subject: [pypy-commit] cffi release-1.12: Modernize this, because very recent pytests crash when seeing the Message-ID: <5cb9ef80.1c69fb81.f1a7.757c@mx.google.com> Author: Armin Rigo Branch: release-1.12 Changeset: r3266:c477011ff6ef Date: 2019-04-19 17:55 +0200 http://bitbucket.org/cffi/cffi/changeset/c477011ff6ef/ Log: Modernize this, because very recent pytests crash when seeing the old way diff --git a/testing/cffi0/test_zintegration.py b/testing/cffi0/test_zintegration.py --- a/testing/cffi0/test_zintegration.py +++ b/testing/cffi0/test_zintegration.py @@ -1,11 +1,13 @@ import py, os, sys, shutil import subprocess from testing.udir import udir +import pytest if sys.platform == 'win32': - py.test.skip('snippets do not run on win32') + pytestmark = pytest.mark.skip('snippets do not run on win32') if sys.version_info < (2, 7): - py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' + pytestmark = pytest.mark.skip( + 'fails e.g. on a Debian/Ubuntu which patches virtualenv' ' in a non-2.6-friendly way') def create_venv(name): diff --git a/testing/embedding/test_performance.py b/testing/embedding/test_performance.py --- a/testing/embedding/test_performance.py +++ b/testing/embedding/test_performance.py @@ -2,8 +2,8 @@ from testing.embedding.test_basic import EmbeddingTests if sys.platform == 'win32': - import py - py.test.skip("written with POSIX functions") + import pytest + pytestmark = pytest.mark.skip("written with POSIX functions") class TestPerformance(EmbeddingTests): From pypy.commits at gmail.com Fri Apr 19 12:15:31 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 09:15:31 -0700 (PDT) Subject: [pypy-commit] cffi release-1.12: tp_hash needs the new type Py_hash_t on CPython 3. Message-ID: <5cb9f423.1c69fb81.e0313.b47f@mx.google.com> Author: Armin Rigo Branch: release-1.12 Changeset: r3267:cdfcd0317d42 Date: 2019-04-19 18:15 +0200 http://bitbucket.org/cffi/cffi/changeset/cdfcd0317d42/ Log: tp_hash needs the new type Py_hash_t on CPython 3. The difference is only relevant on Windows. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2338,7 +2338,11 @@ return pyres; } -static long cdata_hash(CDataObject *v) +#if PY_MAJOR_VERSION < 3 +typedef long Py_hash_t; +#endif + +static Py_hash_t cdata_hash(PyObject *v) { if (((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY) { PyObject *vv = convert_to_object(((CDataObject *)v)->c_data, @@ -2346,13 +2350,13 @@ if (vv == NULL) return -1; if (!CData_Check(vv)) { - long hash = PyObject_Hash(vv); + Py_hash_t hash = PyObject_Hash(vv); Py_DECREF(vv); return hash; } Py_DECREF(vv); } - return _Py_HashPointer(v->c_data); + return _Py_HashPointer(((CDataObject *)v)->c_data); } static Py_ssize_t @@ -3296,7 +3300,7 @@ &CData_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ &CData_as_mapping, /* tp_as_mapping */ - (hashfunc)cdata_hash, /* tp_hash */ + cdata_hash, /* tp_hash */ (ternaryfunc)cdata_call, /* tp_call */ 0, /* tp_str */ (getattrofunc)cdata_getattro, /* tp_getattro */ From pypy.commits at gmail.com Fri Apr 19 12:30:48 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 09:30:48 -0700 (PDT) Subject: [pypy-commit] cffi release-1.12: md5/sha Message-ID: <5cb9f7b8.1c69fb81.7e9c6.1417@mx.google.com> Author: Armin Rigo Branch: release-1.12 Changeset: r3268:bf80722dea36 Date: 2019-04-19 18:29 +0200 http://bitbucket.org/cffi/cffi/changeset/bf80722dea36/ Log: md5/sha diff --git a/doc/source/installation.rst b/doc/source/installation.rst --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -54,11 +54,11 @@ * Checksums of the "source" package version 1.12.3: - - MD5: ... + - MD5: 35ad1f9e1003cac9404c1493eb10d7f5 - - SHA: ... + - SHA: ccc49cf31bc3f4248f45b9ec83685e4e8090a9fa - - SHA256: ... + - SHA256: 041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 * Or grab the most current version from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` From pypy.commits at gmail.com Fri Apr 19 12:30:50 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 09:30:50 -0700 (PDT) Subject: [pypy-commit] cffi release-1.12: Added tag v1.12.3 for changeset bf80722dea36 Message-ID: <5cb9f7ba.1c69fb81.d3463.f462@mx.google.com> Author: Armin Rigo Branch: release-1.12 Changeset: r3269:b9f6ea9a7545 Date: 2019-04-19 18:30 +0200 http://bitbucket.org/cffi/cffi/changeset/b9f6ea9a7545/ Log: Added tag v1.12.3 for changeset bf80722dea36 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -20,3 +20,4 @@ 170fb3d1f0b30d32c9794ea40dbb51836dc7d947 v1.12.0 ac7cb142e8f5dc73033d89c54c54e1b1a6413946 v1.12.1 e0c76668ecf5ab1ad005799cfe1b7cb58610f155 v1.12.2 +bf80722dea36237710083315e336c81bc8571fd0 v1.12.3 From pypy.commits at gmail.com Fri Apr 19 12:30:52 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Apr 2019 09:30:52 -0700 (PDT) Subject: [pypy-commit] cffi default: hg merge release-1.12 Message-ID: <5cb9f7bc.1c69fb81.50150.cfb2@mx.google.com> Author: Armin Rigo Branch: Changeset: r3270:666f45a62a98 Date: 2019-04-19 18:30 +0200 http://bitbucket.org/cffi/cffi/changeset/666f45a62a98/ Log: hg merge release-1.12 diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -20,3 +20,4 @@ 170fb3d1f0b30d32c9794ea40dbb51836dc7d947 v1.12.0 ac7cb142e8f5dc73033d89c54c54e1b1a6413946 v1.12.1 e0c76668ecf5ab1ad005799cfe1b7cb58610f155 v1.12.2 +bf80722dea36237710083315e336c81bc8571fd0 v1.12.3 diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2338,7 +2338,11 @@ return pyres; } -static long cdata_hash(CDataObject *v) +#if PY_MAJOR_VERSION < 3 +typedef long Py_hash_t; +#endif + +static Py_hash_t cdata_hash(PyObject *v) { if (((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY) { PyObject *vv = convert_to_object(((CDataObject *)v)->c_data, @@ -2346,13 +2350,13 @@ if (vv == NULL) return -1; if (!CData_Check(vv)) { - long hash = PyObject_Hash(vv); + Py_hash_t hash = PyObject_Hash(vv); Py_DECREF(vv); return hash; } Py_DECREF(vv); } - return _Py_HashPointer(v->c_data); + return _Py_HashPointer(((CDataObject *)v)->c_data); } static Py_ssize_t @@ -3296,7 +3300,7 @@ &CData_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ &CData_as_mapping, /* tp_as_mapping */ - (hashfunc)cdata_hash, /* tp_hash */ + cdata_hash, /* tp_hash */ (ternaryfunc)cdata_call, /* tp_call */ 0, /* tp_str */ (getattrofunc)cdata_getattro, /* tp_getattro */ diff --git a/c/call_python.c b/c/call_python.c --- a/c/call_python.c +++ b/c/call_python.c @@ -24,6 +24,7 @@ PyThreadState *tstate; PyObject *d, *interpdict; int err; + PyInterpreterState *interp; tstate = PyThreadState_GET(); if (tstate == NULL) { @@ -31,7 +32,7 @@ return NULL; } - PyInterpreterState *interp = tstate->interp; + interp = tstate->interp; #ifdef HAVE_PYINTERPSTATE_GETDICT interpdict = PyInterpreterState_GetDict(interp); /* shared reference */ #else diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -145,6 +145,7 @@ int result; PyGILState_STATE state; PyObject *pycode=NULL, *global_dict=NULL, *x; + PyObject *builtins; state = PyGILState_Ensure(); @@ -169,7 +170,7 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - PyObject *builtins = PyEval_GetBuiltins(); + builtins = PyEval_GetBuiltins(); if (builtins == NULL) goto error; if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) diff --git a/doc/source/installation.rst b/doc/source/installation.rst --- a/doc/source/installation.rst +++ b/doc/source/installation.rst @@ -54,11 +54,11 @@ * Checksums of the "source" package version 1.12.3: - - MD5: ... + - MD5: 35ad1f9e1003cac9404c1493eb10d7f5 - - SHA: ... + - SHA: ccc49cf31bc3f4248f45b9ec83685e4e8090a9fa - - SHA256: ... + - SHA256: 041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 * Or grab the most current version from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` diff --git a/testing/cffi0/test_zintegration.py b/testing/cffi0/test_zintegration.py --- a/testing/cffi0/test_zintegration.py +++ b/testing/cffi0/test_zintegration.py @@ -1,11 +1,13 @@ import py, os, sys, shutil import subprocess from testing.udir import udir +import pytest if sys.platform == 'win32': - py.test.skip('snippets do not run on win32') + pytestmark = pytest.mark.skip('snippets do not run on win32') if sys.version_info < (2, 7): - py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' + pytestmark = pytest.mark.skip( + 'fails e.g. on a Debian/Ubuntu which patches virtualenv' ' in a non-2.6-friendly way') def create_venv(name): diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py --- a/testing/embedding/test_basic.py +++ b/testing/embedding/test_basic.py @@ -63,8 +63,8 @@ output = popen.stdout.read() err = popen.wait() if err: - raise OSError("popen failed with exit code %r: %r" % ( - err, args)) + raise OSError(("popen failed with exit code %r: %r\n\n%s" % ( + err, args, output)).rstrip()) print(output.rstrip()) return output diff --git a/testing/embedding/test_performance.py b/testing/embedding/test_performance.py --- a/testing/embedding/test_performance.py +++ b/testing/embedding/test_performance.py @@ -2,8 +2,8 @@ from testing.embedding.test_basic import EmbeddingTests if sys.platform == 'win32': - import py - py.test.skip("written with POSIX functions") + import pytest + pytestmark = pytest.mark.skip("written with POSIX functions") class TestPerformance(EmbeddingTests): From pypy.commits at gmail.com Fri Apr 19 16:05:37 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Fri, 19 Apr 2019 13:05:37 -0700 (PDT) Subject: [pypy-commit] pypy winmultiprocessing: Work in progress Message-ID: <5cba2a11.1c69fb81.91f4f.d8df@mx.google.com> Author: andrewjlawrence Branch: winmultiprocessing Changeset: r96522:34061c010a7a Date: 2019-04-19 21:02 +0100 http://bitbucket.org/pypy/pypy/changeset/34061c010a7a/ Log: Work in progress diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -101,6 +101,7 @@ HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); +BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD); BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED); BOOL WINAPI PeekNamedPipe(HANDLE, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD); @@ -149,7 +150,7 @@ BOOL WINAPI GetQueuedCompletionStatus(HANDLE, LPDWORD, ULONG**, LPOVERLAPPED*, DWORD); HANDLE WINAPI CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD); -BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); + #define WT_EXECUTEINWAITTHREAD 0x00000004 #define WT_EXECUTEONLYONCE 0x00000008 diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -16,6 +16,7 @@ GetVersion = _kernel32.GetVersion NULL = _ffi.NULL + # Now the _subprocess module implementation def _WinError(type=WindowsError): code, message = _ffi.getwinerror() @@ -109,8 +110,7 @@ @property def event(self): print("Event") - xxx - return None + return _handle2int(self.overlapped[0].hEvent) def GetOverlappedResult(self, wait): print("Get overlapped result") @@ -119,7 +119,8 @@ if res: err = ERROR_SUCCESS else: - err = GetLastError() + err = _kernel32.GetLastError() + print("error {0}".format(err)) if err in (ERROR_SUCCESS, ERROR_MORE_DATA, ERROR_OPERATION_ABORTED): self.completed = 1 self.pending = 0 @@ -136,12 +137,20 @@ def getbuffer(self): print("getbuffer") - xxx - return None + if not self.completed: + raise ValueError("can't get read buffer before GetOverlappedResult() " + "signals the operation completed") + return self.readbuffer def cancel(self): print("cancel") - xxx + ret = True + if self.pending: + ret = _kernel32.CancelIoEx(_int2handle(self.handle), self.overlapped) + if not ret and _kernel32.GetLastError() != ERROR_NOT_FOUND: + # In CPython SetExcFromWindowsErr is called here. + SetFromWindowsErr(0) + self.pending = 0 return None @@ -160,7 +169,7 @@ overlapped = Overlapped(handle) if not overlapped: return _ffi.NULL - overlapped.read_buffer = buf + overlapped.readbuffer = buf if overlapped: ret = _kernel32.ReadFile(_int2handle(handle), buf, size, nread, @@ -185,12 +194,46 @@ if not ret and err != ERROR_MORE_DATA: # In CPython SetExcFromWindowsErr was called here. - return PyErr_SetExcFromWindowsErr(0) + return SetFromWindowsErr(0) return buf, err +def WriteFile(handle, buffer, overlapped=False): + written = _ffi.new("DWORD*") + err = _ffi.new("DWORD*") + use_overlapped = overlapped + overlapped = None -def WriteFile(): - xxx + if use_overlapped: + overlapped = Overlapped(handle) + if not overlapped: + return _ffi.NULL + overlapped.writebuffer = _ffi.new("CHAR[]", bytes(buffer)) + buf = overlapped.writebuffer + else: + buf = _ffi.new("CHAR[]", bytes(buffer)) + + ret = _kernel32.WriteFile(_int2handle(handle), buf , len(buf), written, overlapped.overlapped) + + if ret: + err = 0 + else: + err = _kernel32.GetLastError() + + if overlapped: + if not ret: + if err == ERROR_IO_PENDING: + overlapped.pending = 1 + elif err != ERROR_MORE_DATA: + # In CPython SetExcFromWindowsErr was called here + return SetFromWindowsErr(0) + return overlapped, err + + if not ret: + # In CPython SetExcFromWindowsErr was called here. + return PyErr_SetExcFromWindowsErr(0) + print("written {0}, len(buf) {1}".format(written, len(buf))) + return written, err + def ConnectNamedPipe(handle, overlapped=False): print("Connecting named pipe") From pypy.commits at gmail.com Sat Apr 20 05:39:30 2019 From: pypy.commits at gmail.com (stevie_92) Date: Sat, 20 Apr 2019 02:39:30 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Implemented support for weakrefs in rawrefcount dot tests Message-ID: <5cbae8d2.1c69fb81.9a969.18fb@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96523:b14c3b4ba179 Date: 2019-04-20 11:38 +0200 http://bitbucket.org/pypy/pypy/changeset/b14c3b4ba179/ Log: Implemented support for weakrefs in rawrefcount dot tests Added first dot test with weakrefs Added simple cpython-only-cycle dot test diff --git a/rpython/memory/gc/test/dot/free_cpython_self.dot b/rpython/memory/gc/test/dot/free_cpython_simple.dot copy from rpython/memory/gc/test/dot/free_cpython_self.dot copy to rpython/memory/gc/test/dot/free_cpython_simple.dot --- a/rpython/memory/gc/test/dot/free_cpython_self.dot +++ b/rpython/memory/gc/test/dot/free_cpython_simple.dot @@ -1,4 +1,6 @@ digraph G { "a" [type=C, alive=n]; - "a" -> "a"; + "b" [type=C, alive=n]; + "a" -> "b"; + "b" -> "a"; } diff --git a/rpython/memory/gc/test/dot/free_cpython_self.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot copy from rpython/memory/gc/test/dot/free_cpython_self.dot copy to rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot --- a/rpython/memory/gc/test/dot/free_cpython_self.dot +++ b/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot @@ -1,4 +1,7 @@ digraph G { "a" [type=C, alive=n]; - "a" -> "a"; + "b" [type=C, alive=n]; + "a" -> "b"; + "b" -> "a"; + "a" -> "b" [weakref=y, callback=y, clear_callback=y]; } diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py --- a/rpython/memory/gc/test/test_rawrefcount.py +++ b/rpython/memory/gc/test/test_rawrefcount.py @@ -30,21 +30,34 @@ self.gcobjs = [] self.pyobjs = [] self.pyobj_refs = [] + self.pyobj_weakrefs = [] self.pyobj_finalizer = {} self.pyobj_finalized = {} self.pyobj_resurrect = {} self.pyobj_delete = {} + self.is_pygc = [] def rawrefcount_tp_traverse(obj, callback, args): refs = self.pyobj_refs[self.pyobjs.index(obj)] + weakrefs = self.pyobj_weakrefs[self.pyobjs.index(obj)] for ref in refs: callback(ref, args) + for weakref in weakrefs: + callback(weakref.r, args) def rawrefcount_gc_as_pyobj(gc): - return self.pyobjs[self.gcobjs.index(gc)] + index = self.gcobjs.index(gc) + if self.is_pygc[index]: + return self.pyobjs[index] + else: + assert False def rawrefcount_pyobj_as_gc(pyobj): - return self.gcobjs[self.pyobjs.index(pyobj)] + index = self.pyobjs.index(pyobj) + if self.is_pygc[index]: + return self.gcobjs[index] + else: + return lltype.nullptr(PYOBJ_GC_HDR) def rawrefcount_finalizer_type(gc): pyobj = self.pyobjs[self.gcobjs.index(gc)] @@ -56,6 +69,15 @@ else: return RAWREFCOUNT_FINALIZER_NONE + def rawrefcount_clear_wr(gc): + cleared = False + for weakrefs in self.pyobj_weakrefs: + for weakref in weakrefs: + if gc._obj.container == weakref.p._obj: + weakref.callback_cleared = True + cleared = True + assert cleared + self.pyobj_list = lltype.malloc(PYOBJ_GC_HDR_PTR.TO, flavor='raw', immortal=True) self.pyobj_list.c_gc_next = self.pyobj_list @@ -65,7 +87,8 @@ llmemory.cast_ptr_to_adr(self.pyobj_list), rawrefcount_gc_as_pyobj, rawrefcount_pyobj_as_gc, - rawrefcount_finalizer_type) + rawrefcount_finalizer_type, + rawrefcount_clear_wr) def _collect(self, major, expected_trigger=0): if major: @@ -83,6 +106,11 @@ refs.append(pyobj_to) pyobj_to.c_ob_refcnt += 1 + def _rawrefcount_addweakref(self, pyobj_from, weakref): + refs = self.pyobj_weakrefs[self.pyobjs.index(pyobj_from)] + refs.append(weakref) + weakref.r.c_ob_refcnt += 1 + def _rawrefcount_add_resurrect(self, pyobj_source, pyobj_target): refs = self.pyobj_resurrect[self.pyobjs.index(pyobj_source)] = [] refs.append(pyobj_target) @@ -109,23 +137,26 @@ return p1, p1ref, check_alive - def _rawrefcount_pyobj(self, create_immortal=False): + def _rawrefcount_pyobj(self, create_immortal=False, is_gc=True): r1 = lltype.malloc(PYOBJ_HDR, flavor='raw', immortal=create_immortal) r1.c_ob_refcnt = 0 r1.c_ob_pypy_link = 0 r1addr = llmemory.cast_ptr_to_adr(r1) - r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw', - immortal=True) - r1gc.c_gc_next = self.pyobj_list - r1gc.c_gc_prev = self.pyobj_list.c_gc_prev - r1gc.c_gc_prev.c_gc_next = r1gc - self.pyobj_list.c_gc_prev = r1gc + if is_gc: + r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw', + immortal=True) + r1gc.c_gc_next = self.pyobj_list + r1gc.c_gc_prev = self.pyobj_list.c_gc_prev + r1gc.c_gc_prev.c_gc_next = r1gc + self.pyobj_list.c_gc_prev = r1gc + self.gcobjs.append(r1gc) - self.gcobjs.append(r1gc) self.pyobjs.append(r1) + self.is_pygc.append(is_gc) self.pyobj_refs.append([]) + self.pyobj_weakrefs.append([]) def check_alive(extra_refcount): assert r1.c_ob_refcnt == extra_refcount @@ -134,7 +165,7 @@ def _rawrefcount_pair(self, intval, is_light=False, is_pyobj=False, create_old=False, create_immortal=False, - rooted=False, force_external=False): + rooted=False, force_external=False, is_gc=True): if is_light: rc = REFCNT_FROM_PYPY_LIGHT else: @@ -166,16 +197,19 @@ r1.c_ob_pypy_link = 0 r1addr = llmemory.cast_ptr_to_adr(r1) - r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw', - immortal=True) - r1gc.c_gc_next = self.pyobj_list - r1gc.c_gc_prev = self.pyobj_list.c_gc_prev - r1gc.c_gc_prev.c_gc_next = r1gc - self.pyobj_list.c_gc_prev = r1gc + if is_gc: + r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw', + immortal=True) + r1gc.c_gc_next = self.pyobj_list + r1gc.c_gc_prev = self.pyobj_list.c_gc_prev + r1gc.c_gc_prev.c_gc_next = r1gc + self.pyobj_list.c_gc_prev = r1gc + self.gcobjs.append(r1gc) - self.gcobjs.append(r1gc) self.pyobjs.append(r1) + self.is_pygc.append(is_gc) self.pyobj_refs.append([]) + self.pyobj_weakrefs.append([]) if is_pyobj: assert not is_light @@ -457,6 +491,20 @@ self.delete = delete self.garbage = garbage + class WeakrefNode(BorderNode): + def __init__(self, p, pref, r, raddr, check_alive, info, r_dest, + callback, clear_callback): + self.p = p + self.pref = pref + self.r = r + self.raddr = raddr + self.check_alive = check_alive + self.info = info + self.r_dest = r_dest + self.callback = callback + self.clear_callback = clear_callback + self.callback_cleared = False + path = os.path.join(self.dot_dir, file) g = pydot.graph_from_dot_file(path)[0] nodes = {} @@ -501,17 +549,33 @@ for e in g.get_edges(): source = nodes[e.get_source()] dest = nodes[e.get_destination()] + attr = e.obj_dict['attributes'] + weakref = attr['weakref'] == "y" if 'weakref' in attr else False + callback = attr['callback'] == "y" if 'callback' in attr else False + clear_callback = attr['clear_callback'] == "y" \ + if 'clear_callback' in attr else False if source.info.type == "C" or dest.info.type == "C": - self._rawrefcount_addref(source.r, dest.r) - if source.info.alive: - dest.info.ext_refcnt += 1 + if weakref: + # only weakrefs from C objects supported in tests + assert source.info.type == "C" + p, pref, r, raddr, check_alive = \ + self._rawrefcount_pair(42 + i, rooted=False, + create_old=True, is_gc=False) + weakref = WeakrefNode(p, pref, r, raddr, check_alive, info, + dest.r, callback, clear_callback) + self._rawrefcount_addweakref(source.r, weakref) + i += 1 + else: + self._rawrefcount_addref(source.r, dest.r) + if source.info.alive: + dest.info.ext_refcnt += 1 elif source.info.type == "P" or dest.info.type == "P": if llmemory.cast_ptr_to_adr(source.p.next) == llmemory.NULL: source.p.next = dest.p elif llmemory.cast_ptr_to_adr(source.p.prev) == llmemory.NULL: source.p.prev = dest.p else: - assert False # only 2 refs supported from pypy obj + assert False # only 2 refs supported from pypy obj in tests # add finalizers for name in nodes: @@ -538,10 +602,17 @@ for e in g.get_edges(): source = nodes[e.get_source()] dest = nodes[e.get_destination()] + attr = e.obj_dict['attributes'] + weakref = attr['weakref'] == "y" if 'weakref' in attr else False if source.info.type == "C" or dest.info.type == "C": if not dests_by_source.has_key(source): dests_by_source[source] = [] - dests_by_source[source].append(dest.r) + if weakref: + wrs = self.pyobj_weakrefs[self.pyobjs.index(source.r)] + # currently only one weakref supported + dests_by_source[source].append(wrs[0].r) + else: + dests_by_source[source].append(dest.r) for source in dests_by_source: dests_target = dests_by_source[source] def append(pyobj, ignore): @@ -613,8 +684,12 @@ def clear(pyobj_to, pyobj_from): refs = self.pyobj_refs[self.pyobjs.index(pyobj_from)] - refs.remove(pyobj_to) - decref(pyobj_to, None) + weakrefs = self.pyobj_weakrefs[self.pyobjs.index(pyobj_from)] + if pyobj_to in refs: + refs.remove(pyobj_to) + decref(pyobj_to, None) + else: + pass # weakref self.gc.rrc_tp_traverse(pyobj, clear, pyobj) @@ -667,6 +742,14 @@ else: py.test.raises(RuntimeError, "n.r.c_ob_refcnt") # dead + # check if all callbacks from weakrefs from cyclic garbage structures, + # which should not be called because they could ressurrect dead + # objects, have been cleared and no other callbacks were cleared; see: + # https://github.com/python/cpython/blob/master/Modules/gc_weakref.txt + for weakrefs in self.pyobj_weakrefs: + for weakref in weakrefs: + assert weakref.callback_cleared == weakref.clear_callback + # check if unreachable objects in cyclic structures with legacy # finalizers and all otherwise unreachable objects reachable from them # have been added to the garbage list From pypy.commits at gmail.com Sat Apr 20 08:23:27 2019 From: pypy.commits at gmail.com (stevie_92) Date: Sat, 20 Apr 2019 05:23:27 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Fixed an error in rawrefcount dot tests and added a weakref test Message-ID: <5cbb0f3f.1c69fb81.99dd3.495b@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96524:3466abcd4f70 Date: 2019-04-20 14:22 +0200 http://bitbucket.org/pypy/pypy/changeset/3466abcd4f70/ Log: Fixed an error in rawrefcount dot tests and added a weakref test diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot copy from rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot copy to rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot --- a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot +++ b/rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot @@ -4,4 +4,5 @@ "a" -> "b"; "b" -> "a"; "a" -> "b" [weakref=y, callback=y, clear_callback=y]; + "b" -> "a" [weakref=y, callback=y, clear_callback=y]; } diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py --- a/rpython/memory/gc/test/test_rawrefcount.py +++ b/rpython/memory/gc/test/test_rawrefcount.py @@ -76,7 +76,6 @@ if gc._obj.container == weakref.p._obj: weakref.callback_cleared = True cleared = True - assert cleared self.pyobj_list = lltype.malloc(PYOBJ_GC_HDR_PTR.TO, flavor='raw', immortal=True) From pypy.commits at gmail.com Sat Apr 20 08:29:32 2019 From: pypy.commits at gmail.com (stevie_92) Date: Sat, 20 Apr 2019 05:29:32 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Improved weakref support for rawrefcount dot tests and added test Message-ID: <5cbb10ac.1c69fb81.d3463.aa09@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96525:31150aa29431 Date: 2019-04-20 14:29 +0200 http://bitbucket.org/pypy/pypy/changeset/31150aa29431/ Log: Improved weakref support for rawrefcount dot tests and added test diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_multi_1.dot rename from rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot rename to rpython/memory/gc/test/dot/free_cpython_weakref_multi_1.dot diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_multi_2.dot copy from rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot copy to rpython/memory/gc/test/dot/free_cpython_weakref_multi_2.dot --- a/rpython/memory/gc/test/dot/free_cpython_weakref_multi.dot +++ b/rpython/memory/gc/test/dot/free_cpython_weakref_multi_2.dot @@ -4,5 +4,5 @@ "a" -> "b"; "b" -> "a"; "a" -> "b" [weakref=y, callback=y, clear_callback=y]; - "b" -> "a" [weakref=y, callback=y, clear_callback=y]; + "a" -> "b" [weakref=y, callback=y, clear_callback=y]; } diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py --- a/rpython/memory/gc/test/test_rawrefcount.py +++ b/rpython/memory/gc/test/test_rawrefcount.py @@ -598,6 +598,7 @@ # quick self check, if traverse works properly dests_by_source = {} + weakrefs_added = [] for e in g.get_edges(): source = nodes[e.get_source()] dest = nodes[e.get_destination()] @@ -607,9 +608,11 @@ if not dests_by_source.has_key(source): dests_by_source[source] = [] if weakref: - wrs = self.pyobj_weakrefs[self.pyobjs.index(source.r)] - # currently only one weakref supported - dests_by_source[source].append(wrs[0].r) + if source not in weakrefs_added: # add all weakrefs at once + weakrefs_added.append(source) + wrs = self.pyobj_weakrefs[self.pyobjs.index(source.r)] + for wr in wrs: + dests_by_source[source].append(wr.r) else: dests_by_source[source].append(dest.r) for source in dests_by_source: From pypy.commits at gmail.com Sat Apr 20 08:47:11 2019 From: pypy.commits at gmail.com (stevie_92) Date: Sat, 20 Apr 2019 05:47:11 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Added some weakref tests to dot tests to cover important cases Message-ID: <5cbb14cf.1c69fb81.b027f.0037@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96526:e3d2ca7b1fe6 Date: 2019-04-20 14:46 +0200 http://bitbucket.org/pypy/pypy/changeset/e3d2ca7b1fe6/ Log: Added some weakref tests to dot tests to cover important cases diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot rename from rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot rename to rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_2.dot copy from rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot copy to rpython/memory/gc/test/dot/free_cpython_weakref_simple_2.dot --- a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot +++ b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_2.dot @@ -1,7 +1,8 @@ digraph G { "a" [type=C, alive=n]; "b" [type=C, alive=n]; + "c" [type=C, alive=y, ext_refcnt=1]; "a" -> "b"; "b" -> "a"; - "a" -> "b" [weakref=y, callback=y, clear_callback=y]; + "a" -> "c" [weakref=y, callback=y, clear_callback=y]; } diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_3.dot copy from rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot copy to rpython/memory/gc/test/dot/free_cpython_weakref_simple_3.dot --- a/rpython/memory/gc/test/dot/free_cpython_weakref_simple.dot +++ b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_3.dot @@ -1,7 +1,8 @@ digraph G { "a" [type=C, alive=n]; "b" [type=C, alive=n]; + "c" [type=C, alive=y, ext_refcnt=1]; "a" -> "b"; "b" -> "a"; - "a" -> "b" [weakref=y, callback=y, clear_callback=y]; + "c" -> "a" [weakref=y, callback=y, clear_callback=n]; } From pypy.commits at gmail.com Sat Apr 20 08:54:42 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 20 Apr 2019 05:54:42 -0700 (PDT) Subject: [pypy-commit] pypy winmultiprocessing: tidy up and attempt to fix some bugs. Message-ID: <5cbb1692.1c69fb81.e246d.63c7@mx.google.com> Author: andrewjlawrence Branch: winmultiprocessing Changeset: r96527:3f2da06e0f60 Date: 2019-04-20 13:52 +0100 http://bitbucket.org/pypy/pypy/changeset/3f2da06e0f60/ Log: tidy up and attempt to fix some bugs. diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -94,7 +94,6 @@ _kernel32.CreateEventW(NULL, True, False, NULL) def __del__(self): - print("Deleting overlapped") # do this somehow else err = _kernel32.GetLastError() bytes = _ffi.new('DWORD[1]') @@ -109,18 +108,16 @@ @property def event(self): - print("Event") return _handle2int(self.overlapped[0].hEvent) def GetOverlappedResult(self, wait): - print("Get overlapped result") transferred = _ffi.new('DWORD[1]', [0]) - res = _kernel32.GetOverlappedResult(_int2handle(self.handle), self.overlapped, transferred, wait != 0) + res = _kernel32.GetOverlappedResult(_int2handle(self.handle), self.overlapped, transferred, wait) if res: err = ERROR_SUCCESS else: err = _kernel32.GetLastError() - print("error {0}".format(err)) + if err in (ERROR_SUCCESS, ERROR_MORE_DATA, ERROR_OPERATION_ABORTED): self.completed = 1 self.pending = 0 @@ -128,22 +125,24 @@ pass else: self.pending = 0 - raise _WinError() + raise _WinError(IOError) + if self.completed and self.readbuffer: - if transferred != len(self.readbuffer): - raise _WinError() - print("Leaving getoverlappedresult") + assert _ffi.typeof(self.readbuffer) is _ffi.typeof("CHAR[]") + if transferred[0] != len(self.readbuffer): + tempbuffer = _ffi.new("CHAR[]", transferred[0]) + _ffi.memmove(tempbuffer, self.readbuffer, transferred[0]) + self.readbuffer = tempbuffer + return None return transferred[0], err def getbuffer(self): - print("getbuffer") if not self.completed: raise ValueError("can't get read buffer before GetOverlappedResult() " "signals the operation completed") return self.readbuffer def cancel(self): - print("cancel") ret = True if self.pending: ret = _kernel32.CancelIoEx(_int2handle(self.handle), self.overlapped) @@ -155,7 +154,6 @@ def ReadFile(handle, size, overlapped): - print("ReadFile entered") nread = _ffi.new("DWORD*") err = _ffi.new("DWORD*") use_overlapped = overlapped @@ -182,19 +180,16 @@ err = 0 else: err = _kernel32.GetLastError() - print("Error {0}".format(err)) if overlapped: if not ret: if err == ERROR_IO_PENDING: overlapped.pending = 1 elif err != ERROR_MORE_DATA: - # In CPython SetExcFromWindowsErr was called here - return SetFromWindowsErr(0) + return _WinError(IOError) return overlapped, err if not ret and err != ERROR_MORE_DATA: - # In CPython SetExcFromWindowsErr was called here. - return SetFromWindowsErr(0) + return _WinError(IOError) return buf, err def WriteFile(handle, buffer, overlapped=False): @@ -224,19 +219,22 @@ if err == ERROR_IO_PENDING: overlapped.pending = 1 elif err != ERROR_MORE_DATA: - # In CPython SetExcFromWindowsErr was called here - return SetFromWindowsErr(0) + return _WinError(IOError) + + assert written == len(overlapped.writebuffer) return overlapped, err if not ret: - # In CPython SetExcFromWindowsErr was called here. - return PyErr_SetExcFromWindowsErr(0) - print("written {0}, len(buf) {1}".format(written, len(buf))) + return _WinError(IOError) + + # The whole of the buffer should have been written + # otherwise this function call has been be successful + assert written == len(buf) + return written, err def ConnectNamedPipe(handle, overlapped=False): - print("Connecting named pipe") handle = _int2handle(handle) if overlapped: ov = Overlapped(handle) @@ -263,7 +261,6 @@ def DuplicateHandle(source_process, source, target_process, access, inherit, options=0): # CPython: the first three arguments are expected to be integers - print("DuplicateHandle") target = _ffi.new("HANDLE[1]") res = _kernel32.DuplicateHandle( @@ -275,7 +272,6 @@ if not res: raise _WinError() - print("Leaving DuplicateHandle") return _handle2int(target[0]) def _Z(input): @@ -325,7 +321,6 @@ pi.dwThreadId) def OpenProcess(desired_access, inherit_handle, process_id): - print("OpenProcess") handle = _kernel32.OpenProcess(desired_access, inherit_handle, process_id) if handle == _ffi.NULL: SetFromWindowsErr(0) @@ -334,7 +329,6 @@ return _handle2int(handle) def PeekNamedPipe(handle, size=0): - print("Entering Peek Named Pipe") nread = _ffi.new("DWORD*") navail = _ffi.new("DWORD*") nleft = _ffi.new("DWORD*") @@ -356,7 +350,6 @@ # if (_PyBytes_Resize(&buf, nread)) # return NULL; - print("Leaving print named pipe") return buf, navail, nleft else: ret = _kernel32.PeekNamedPipe(_int2handle(handle), _ffi.NULL, 0, _ffi.NULL, navail, nleft) @@ -364,29 +357,25 @@ # In CPython SetExcFromWindowsErr is called here. # Not sure what that is doing currently. SetFromWindowsErr(0) - print("Leaving print named pipe") return navail, nleft def WaitForSingleObject(handle, milliseconds): - print("Entering waitforsingle object") # CPython: the first argument is expected to be an integer. res = _kernel32.WaitForSingleObject(_int2handle(handle), milliseconds) if res < 0: raise _WinError() - print("leavng waitforsingle object") return res def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds): - print("Entering waitformultipleobjects") if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS: return None - + handle_sequence = list(map(_int2handle, handle_sequence)) + handle_sequence = _ffi.new("HANDLE[]", handle_sequence) # CPython makes the wait interruptible by ctrl-c. We need to add this in at some point res = _kernel32.WaitForMultipleObjects(len(handle_sequence), handle_sequence, waitflag, milliseconds) if res == WAIT_FAILED: raise _WinError() - print("leaving waitformultipleobjects") return int(res) @@ -402,7 +391,6 @@ return code[0] def TerminateProcess(handle, exitcode): - print("Terminating process") # CPython: the first argument is expected to be an integer. # The second argument is silently wrapped in a UINT. res = _kernel32.TerminateProcess(_int2handle(handle), diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -37,13 +37,6 @@ def sem_unlink(name): return None - - def semaphore_unlink(space, w_name): - name = space.text_w(w_name) - try: - sem_unlink(name) - except OSError as e: - raise wrap_oserror(space, e) else: from rpython.rlib import rposix @@ -222,12 +215,13 @@ def handle_w(space, w_handle): return rffi.cast(SEM_T, space.int_w(w_handle)) - def semaphore_unlink(space, w_name): - name = space.text_w(w_name) - try: - sem_unlink(name) - except OSError as e: - raise wrap_oserror(space, e) +# utilized by POSIX and win32 +def semaphore_unlink(space, w_name): + name = space.text_w(w_name) + try: + sem_unlink(name) + except OSError as e: + raise wrap_oserror(space, e) class CounterState: def __init__(self, space): From pypy.commits at gmail.com Sat Apr 20 15:55:55 2019 From: pypy.commits at gmail.com (andrewjlawrence) Date: Sat, 20 Apr 2019 12:55:55 -0700 (PDT) Subject: [pypy-commit] pypy winmultiprocessing: Fixed a load of multiprocessing tests. Message-ID: <5cbb794b.1c69fb81.e252.0d7d@mx.google.com> Author: andrewjlawrence Branch: winmultiprocessing Changeset: r96528:173fa2d8f8a1 Date: 2019-04-20 20:54 +0100 http://bitbucket.org/pypy/pypy/changeset/173fa2d8f8a1/ Log: Fixed a load of multiprocessing tests. diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -101,6 +101,7 @@ HANDLE WINAPI CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); +BOOL WaitNamedPipeA(LPCSTR, DWORD); BOOL WINAPI WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); BOOL WINAPI SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD); BOOL WINAPI ConnectNamedPipe(HANDLE, LPOVERLAPPED); diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py --- a/lib_pypy/_pypy_winbase_cffi.py +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -3,8 +3,8 @@ ffi = _cffi_backend.FFI('_pypy_winbase_cffi', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x75\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x4F\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1A\x03\x00\x01\x48\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x59\x03\x00\x00\x27\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x27\x11\x00\x00\x27\x11\x00\x01\x54\x03\x00\x01\x49\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x33\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x33\x11\x00\x00\x11\x11\x00\x01\x3F\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x21\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x22\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x55\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x22\x11\x00\x01\x3A\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x5E\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x03\x00\x00\x22\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x63\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x21\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x33\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x75\x03\x00\x00\x0A\x01\x00\x00\x21\x11\x00\x00\x22\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xEA\x03\x00\x00\x07\x01\x00\x01\x58\x03\x00\x00\x15\x11\x00\x00\x01\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\xBB\x11\x00\x00\xBB\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xBB\x11\x00\x00\xBB\x11\x00\x00\x2F\x11\x00\x00\x30\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x70\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x0A\x01\x00\x00\x33\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x11\x11\x00\x00\xBB\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x1A\x0D\x00\x00\x02\x0F\x00\x00\xE5\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xE5\x0D\x00\x00\x00\x0F\x00\x00\xE5\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x00\x00\x0F\x00\x00\x11\x0D\x00\x01\x4E\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x01\x59\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xF9\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xEA\x03\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xFC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xF9\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xFC\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xF9\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\xBB\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xF9\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x01\x02\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xF9\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x02\x0F\x00\x01\x75\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x11\x11\x00\x00\x00\x0F\x00\x01\x75\x0D\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x45\x03\x00\x00\x13\x09\x00\x01\x47\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x4B\x03\x00\x00\x0E\x09\x00\x01\x4D\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x53\x03\x00\x01\x52\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x57\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x59\x05\x00\x00\x00\x0E\x00\x01\x59\x05\x00\x00\x00\x08\x00\x00\x4D\x03\x00\x00\x53\x03\x00\x00\xA0\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x6C\x03\x00\x00\x04\x01\x00\x01\x6C\x05\x00\x00\x00\x10\x00\x01\x6C\x05\x00\x00\x00\x08\x00\x00\x1A\x05\x00\x00\x00\x07\x00\x00\xE5\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xEA\x05\x00\x00\x01\x00', - _globals = (b'\x00\x00\x40\x23CancelIo',0,b'\x00\x00\x43\x23CancelIoEx',0,b'\x00\x00\x40\x23CloseHandle',0,b'\x00\x00\x43\x23ConnectNamedPipe',0,b'\x00\x00\xF8\x23CreateEventA',0,b'\x00\x00\xFE\x23CreateEventW',0,b'\x00\x01\x04\x23CreateFileA',0,b'\x00\x01\x31\x23CreateFileW',0,b'\x00\x01\x1F\x23CreateIoCompletionPort',0,b'\x00\x01\x0D\x23CreateNamedPipeA',0,b'\x00\x01\x27\x23CreateNamedPipeW',0,b'\x00\x00\x32\x23CreatePipe',0,b'\x00\x00\x26\x23CreateProcessA',0,b'\x00\x00\xC1\x23CreateProcessW',0,b'\x00\x00\xAA\x23DuplicateHandle',0,b'\x00\x01\x25\x23GetCurrentProcess',0,b'\x00\x00\x72\x23GetExitCodeProcess',0,b'\x00\x00\xE2\x23GetLastError',0,b'\x00\x00\xDD\x23GetModuleFileNameW',0,b'\x00\x00\x47\x23GetOverlappedResult',0,b'\x00\x00\xF6\x23GetProcessHeap',0,b'\x00\x00\x76\x23GetQueuedCompletionStatus',0,b'\x00\x01\x1C\x23GetStdHandle',0,b'\x00\x00\xE2\x23GetVersion',0,b'\x00\x00\xF1\x23HeapAlloc',0,b'\x00\x00\x18\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\xEC\x23OpenProcess',0,b'\x00\x00\x98\x23PeekNamedPipe',0,b'\x00\x00\x83\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1D\x23ReadFile',0,b'\x00\x00\x38\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xD0\x23SetErrorMode',0,b'\x00\x00\x40\x23SetEvent',0,b'\x00\x00\x7D\x23SetNamedPipeHandleState',0,b'\x00\x00\x6E\x23TerminateProcess',0,b'\x00\x00\x40\x23UnregisterWait',0,b'\x00\x00\x94\x23UnregisterWaitEx',0,b'\x00\x00\x89\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x5C\x23WSARecv',0,b'\x00\x00\x65\x23WSASend',0,b'\x00\x00\xBA\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xD3\x23WaitForMultipleObjects',0,b'\x00\x00\xD9\x23WaitForSingleObject',0,b'\x00\x00\xB3\x23WriteFile',0,b'\x00\x00\xCD\x23_get_osfhandle',0,b'\x00\x00\x24\x23_getch',0,b'\x00\x00\x24\x23_getche',0,b'\x00\x00\xE7\x23_getwch',0,b'\x00\x00\xE7\x23_getwche',0,b'\x00\x00\x24\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\xE9\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\xE4\x23_ungetwch',0,b'\x00\x00\x13\x23bind',0,b'\x00\x00\x10\x23closesocket',0,b'\x00\x00\xE4\x23htons',0,b'\x00\x01\x17\x23socket',0), - _struct_unions = ((b'\x00\x00\x01\x66\x00\x00\x00\x03$1',b'\x00\x01\x62\x11DUMMYSTRUCTNAME',b'\x00\x00\x11\x11Pointer'),(b'\x00\x00\x01\x62\x00\x00\x00\x02$2',b'\x00\x00\x1A\x11Offset',b'\x00\x00\x1A\x11OffsetHigh'),(b'\x00\x00\x01\x67\x00\x00\x00\x03$3',b'\x00\x01\x6D\x11Byte',b'\x00\x01\x73\x11Word'),(b'\x00\x00\x01\x68\x00\x00\x00\x01$4',b'\x00\x01\x63\x11',b'\x00\x00\x1A\x11Value'),(b'\x00\x00\x01\x63\x00\x00\x00\x02$5',b'\x00\x00\x1A\x13\x00\x00\x00\x1CZone',b'\x00\x00\x1A\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x69\x00\x00\x00\x03$6',b'\x00\x00\x1A\x11sin6_scope_id',b'\x00\x01\x4D\x11sin6_scope_struct'),(b'\x00\x00\x01\x6A\x00\x00\x00\x03$7',b'\x00\x01\x64\x11S_un_b',b'\x00\x01\x65\x11S_un_w',b'\x00\x00\x1A\x11S_addr'),(b'\x00\x00\x01\x64\x00\x00\x00\x02$8',b'\x00\x01\x6C\x11s_b1',b'\x00\x01\x6C\x11s_b2',b'\x00\x01\x6C\x11s_b3',b'\x00\x01\x6C\x11s_b4'),(b'\x00\x00\x01\x65\x00\x00\x00\x02$9',b'\x00\x00\xE5\x11s_w1',b'\x00\x00\xE5\x11s_w2'),(b'\x00\x00\x01\x49\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x11\x11hProcess',b'\x00\x00\x11\x11hThread',b'\x00\x00\x1A\x11dwProcessId',b'\x00\x00\x1A\x11dwThreadId'),(b'\x00\x00\x01\x4D\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x68\x11'),(b'\x00\x00\x01\x54\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x1A\x11cb',b'\x00\x00\x27\x11lpReserved',b'\x00\x00\x27\x11lpDesktop',b'\x00\x00\x27\x11lpTitle',b'\x00\x00\x1A\x11dwX',b'\x00\x00\x1A\x11dwY',b'\x00\x00\x1A\x11dwXSize',b'\x00\x00\x1A\x11dwYSize',b'\x00\x00\x1A\x11dwXCountChars',b'\x00\x00\x1A\x11dwYCountChars',b'\x00\x00\x1A\x11dwFillAttribute',b'\x00\x00\x1A\x11dwFlags',b'\x00\x00\xE5\x11wShowWindow',b'\x00\x00\xE5\x11cbReserved2',b'\x00\x01\x6B\x11lpReserved2',b'\x00\x00\x11\x11hStdInput',b'\x00\x00\x11\x11hStdOutput',b'\x00\x00\x11\x11hStdError'),(b'\x00\x00\x01\x43\x00\x00\x00\x02_GUID',b'\x00\x00\x1A\x11Data1',b'\x00\x00\xE5\x11Data2',b'\x00\x00\xE5\x11Data3',b'\x00\x01\x6F\x11Data4'),(b'\x00\x00\x01\x48\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x1A\x11Internal',b'\x00\x00\x1A\x11InternalHigh',b'\x00\x01\x66\x11DUMMYUNIONNAME',b'\x00\x00\x11\x11hEvent'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x11\x11hCompletionPort',b'\x00\x00\x22\x11Overlapped'),(b'\x00\x00\x01\x4E\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x1A\x11nLength',b'\x00\x00\x11\x11lpSecurityDescriptor',b'\x00\x00\x01\x11bInheritHandle'),(b'\x00\x00\x01\x55\x00\x00\x00\x02_WSABUF',b'\x00\x00\x1A\x11len',b'\x00\x00\x27\x11buf'),(b'\x00\x00\x01\x57\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x01\x11ChainLen',b'\x00\x01\x71\x11ChainEntries'),(b'\x00\x00\x01\x58\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x1A\x11dwServiceFlags1',b'\x00\x00\x1A\x11dwServiceFlags2',b'\x00\x00\x1A\x11dwServiceFlags3',b'\x00\x00\x1A\x11dwServiceFlags4',b'\x00\x00\x1A\x11dwProviderFlags',b'\x00\x01\x43\x11ProviderId',b'\x00\x00\x1A\x11dwCatalogEntryId',b'\x00\x01\x57\x11ProtocolChain',b'\x00\x00\x01\x11iVersion',b'\x00\x00\x01\x11iAddressFamily',b'\x00\x00\x01\x11iMaxSockAddr',b'\x00\x00\x01\x11iMinSockAddr',b'\x00\x00\x01\x11iSocketType',b'\x00\x00\x01\x11iProtocol',b'\x00\x00\x01\x11iProtocolMaxOffset',b'\x00\x00\x01\x11iNetworkByteOrder',b'\x00\x00\x01\x11iSecurityScheme',b'\x00\x00\x1A\x11dwMessageSize',b'\x00\x00\x1A\x11dwProviderReserved',b'\x00\x01\x76\x11szProtocol'),(b'\x00\x00\x01\x45\x00\x00\x00\x02in6_addr',b'\x00\x01\x67\x11u'),(b'\x00\x00\x01\x47\x00\x00\x00\x02in_addr',b'\x00\x01\x6A\x11S_un'),(b'\x00\x00\x01\x4F\x00\x00\x00\x02sockaddr',b'\x00\x00\xE5\x11sa_family',b'\x00\x01\x5A\x11sa_data'),(b'\x00\x00\x01\x53\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x61\x11sin_family',b'\x00\x00\xE5\x11sin_port',b'\x00\x01\x47\x11sin_addr',b'\x00\x01\x5C\x11sin_zero'),(b'\x00\x00\x01\x52\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xE5\x11sin6_family',b'\x00\x00\xE5\x11sin6_port',b'\x00\x00\x1A\x11sin6_flowinfo',b'\x00\x01\x45\x11sin6_addr',b'\x00\x01\x69\x11')), - _typenames = (b'\x00\x00\x00\xE5ADDRESS_FAMILY',b'\x00\x00\x01\x60AcceptExPtr',b'\x00\x00\x01\x5FConnectExPtr',b'\x00\x00\x01\x5EDisconnectExPtr',b'\x00\x00\x01\x43GUID',b'\x00\x00\x01\x45IN6_ADDR',b'\x00\x00\x01\x47INADDR',b'\x00\x00\x01\x5ELPFN_DISCONNECTEX',b'\x00\x00\x01\x44LPIN6_ADDR',b'\x00\x00\x00\x22LPOVERLAPPED',b'\x00\x00\x00\x63LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x30LPPROCESS_INFORMATION',b'\x00\x00\x01\x4ALPPostCallbackData',b'\x00\x00\x00\xF9LPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15LPSOCKADDR',b'\x00\x00\x01\x50LPSOCKADDR_IN',b'\x00\x00\x01\x51LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x2FLPSTARTUPINFO',b'\x00\x00\x00\x5ELPWSABUF',b'\x00\x00\x01\x56LPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xBDLPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x48OVERLAPPED',b'\x00\x00\x01\x44PIN6_ADDR',b'\x00\x00\x01\x46PINADDR',b'\x00\x00\x01\x49PROCESS_INFORMATION',b'\x00\x00\x01\x4CPSCOPE_ID',b'\x00\x00\x00\xF9PSECURITY_ATTRIBUTES',b'\x00\x00\x00\x15PSOCKADDR',b'\x00\x00\x01\x50PSOCKADDR_IN',b'\x00\x00\x01\x51PSOCKADDR_IN6_LH',b'\x00\x00\x01\x4BPostCallbackData',b'\x00\x00\x01\x4DSCOPE_ID',b'\x00\x00\x01\x4ESECURITY_ATTRIBUTES',b'\x00\x00\x01\x4FSOCKADDR',b'\x00\x00\x01\x53SOCKADDR_IN',b'\x00\x00\x01\x52SOCKADDR_IN6_LH',b'\x00\x00\x00\x11SOCKET',b'\x00\x00\x01\x54STARTUPINFO',b'\x00\x00\x00\x3BWAITORTIMERCALLBACK',b'\x00\x00\x01\x55WSABUF',b'\x00\x00\x01\x57WSAPROTOCOLCHAIN',b'\x00\x00\x01\x58WSAPROTOCOL_INFOW',b'\x00\x00\x00\xE5wint_t'), + _types = b'\x00\x00\x05\x0D\x00\x01\x5D\x03\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x01\x79\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x01\x53\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x03\x00\x01\x4C\x03\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x00\x00\x0F\x00\x00\x05\x0D\x00\x01\x5D\x03\x00\x00\x2B\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x2B\x11\x00\x00\x2B\x11\x00\x01\x58\x03\x00\x01\x4D\x03\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x03\x00\x00\x37\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x37\x11\x00\x00\x15\x11\x00\x01\x43\x03\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x26\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x26\x11\x00\x00\x25\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x26\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x19\x11\x00\x00\x07\x01\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x26\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x01\x59\x03\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x25\x11\x00\x00\x26\x11\x00\x01\x3E\x03\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x62\x11\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x0A\x01\x00\x00\x26\x11\x00\x00\x67\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x25\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x25\x11\x00\x00\x25\x03\x00\x00\x26\x03\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x25\x11\x00\x00\x25\x11\x00\x00\x25\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x26\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x26\x11\x00\x00\x67\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x25\x11\x00\x00\x25\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x26\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x37\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\x15\x11\x00\x01\x79\x03\x00\x00\x0A\x01\x00\x00\x25\x11\x00\x00\x26\x11\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\xEE\x03\x00\x00\x07\x01\x00\x01\x5C\x03\x00\x00\x19\x11\x00\x00\x05\x03\x00\x00\x02\x0F\x00\x00\x05\x0D\x00\x00\xBF\x11\x00\x00\xBF\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\xBF\x11\x00\x00\xBF\x11\x00\x00\x33\x11\x00\x00\x34\x11\x00\x00\x02\x0F\x00\x00\x11\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x74\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x02\x0D\x00\x00\x0A\x01\x00\x00\x37\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x02\x0D\x00\x00\x15\x11\x00\x00\xBF\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x02\x0D\x00\x00\x02\x0F\x00\x00\xE9\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\xE9\x0D\x00\x00\x00\x0F\x00\x00\xE9\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x01\x52\x03\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x01\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\xFD\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\xEE\x03\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x01\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xFD\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x01\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xFD\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\xBF\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xFD\x11\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x01\x06\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\xFD\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x01\x79\x0D\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x15\x11\x00\x00\x00\x0F\x00\x01\x79\x0D\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x0C\x09\x00\x01\x49\x03\x00\x00\x13\x09\x00\x01\x4B\x03\x00\x00\x14\x09\x00\x00\x0D\x09\x00\x00\x09\x09\x00\x01\x4F\x03\x00\x00\x0E\x09\x00\x01\x51\x03\x00\x00\x0A\x09\x00\x00\x0F\x09\x00\x00\x15\x09\x00\x01\x57\x03\x00\x01\x56\x03\x00\x00\x17\x09\x00\x00\x16\x09\x00\x00\x0B\x09\x00\x00\x10\x09\x00\x01\x5B\x03\x00\x00\x11\x09\x00\x00\x12\x09\x00\x00\x02\x01\x00\x01\x5D\x05\x00\x00\x00\x0E\x00\x01\x5D\x05\x00\x00\x00\x08\x00\x00\x51\x03\x00\x00\x57\x03\x00\x00\xA4\x03\x00\x00\x05\x01\x00\x00\x01\x09\x00\x00\x04\x09\x00\x00\x07\x09\x00\x00\x08\x09\x00\x00\x00\x09\x00\x00\x02\x09\x00\x00\x03\x09\x00\x00\x05\x09\x00\x00\x06\x09\x00\x01\x70\x03\x00\x00\x04\x01\x00\x01\x70\x05\x00\x00\x00\x10\x00\x01\x70\x05\x00\x00\x00\x08\x00\x00\x02\x05\x00\x00\x00\x07\x00\x00\xE9\x05\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\xEE\x05\x00\x00\x01\x00', + _globals = (b'\x00\x00\x44\x23CancelIo',0,b'\x00\x00\x47\x23CancelIoEx',0,b'\x00\x00\x44\x23CloseHandle',0,b'\x00\x00\x47\x23ConnectNamedPipe',0,b'\x00\x00\xFC\x23CreateEventA',0,b'\x00\x01\x02\x23CreateEventW',0,b'\x00\x01\x08\x23CreateFileA',0,b'\x00\x01\x35\x23CreateFileW',0,b'\x00\x01\x23\x23CreateIoCompletionPort',0,b'\x00\x01\x11\x23CreateNamedPipeA',0,b'\x00\x01\x2B\x23CreateNamedPipeW',0,b'\x00\x00\x36\x23CreatePipe',0,b'\x00\x00\x2A\x23CreateProcessA',0,b'\x00\x00\xC5\x23CreateProcessW',0,b'\x00\x00\xAE\x23DuplicateHandle',0,b'\x00\x01\x29\x23GetCurrentProcess',0,b'\x00\x00\x76\x23GetExitCodeProcess',0,b'\x00\x00\xE6\x23GetLastError',0,b'\x00\x00\xE1\x23GetModuleFileNameW',0,b'\x00\x00\x4B\x23GetOverlappedResult',0,b'\x00\x00\xFA\x23GetProcessHeap',0,b'\x00\x00\x7A\x23GetQueuedCompletionStatus',0,b'\x00\x01\x20\x23GetStdHandle',0,b'\x00\x00\xE6\x23GetVersion',0,b'\x00\x00\xF5\x23HeapAlloc',0,b'\x00\x00\x1C\x23HeapFree',0,b'\xFF\xFF\xFF\x1FMAX_PROTOCOL_CHAIN',7,b'\x00\x00\xF0\x23OpenProcess',0,b'\x00\x00\x9C\x23PeekNamedPipe',0,b'\x00\x00\x87\x23PostQueuedCompletionStatus',0,b'\x00\x00\x21\x23ReadFile',0,b'\x00\x00\x3C\x23RegisterWaitForSingleObject',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\xD4\x23SetErrorMode',0,b'\x00\x00\x44\x23SetEvent',0,b'\x00\x00\x81\x23SetNamedPipeHandleState',0,b'\x00\x00\x72\x23TerminateProcess',0,b'\x00\x00\x44\x23UnregisterWait',0,b'\x00\x00\x98\x23UnregisterWaitEx',0,b'\x00\x00\x8D\x23WSAIoctl',0,b'\xFF\xFF\xFF\x1FWSAPROTOCOL_LEN',255,b'\x00\x00\x60\x23WSARecv',0,b'\x00\x00\x69\x23WSASend',0,b'\x00\x00\xBE\x23WSAStringToAddressW',0,b'\xFF\xFF\xFF\x1FWT_EXECUTEINWAITTHREAD',4,b'\xFF\xFF\xFF\x1FWT_EXECUTEONLYONCE',8,b'\x00\x00\xD7\x23WaitForMultipleObjects',0,b'\x00\x00\xDD\x23WaitForSingleObject',0,b'\x00\x00\x00\x23WaitNamedPipeA',0,b'\x00\x00\xB7\x23WriteFile',0,b'\x00\x00\xD1\x23_get_osfhandle',0,b'\x00\x00\x28\x23_getch',0,b'\x00\x00\x28\x23_getche',0,b'\x00\x00\xEB\x23_getwch',0,b'\x00\x00\xEB\x23_getwche',0,b'\x00\x00\x28\x23_kbhit',0,b'\x00\x00\x0B\x23_locking',0,b'\x00\x00\x10\x23_open_osfhandle',0,b'\x00\x00\x04\x23_putch',0,b'\x00\x00\xED\x23_putwch',0,b'\x00\x00\x07\x23_setmode',0,b'\x00\x00\x04\x23_ungetch',0,b'\x00\x00\xE8\x23_ungetwch',0,b'\x00\x00\x17\x23bind',0,b'\x00\x00\x14\x23closesocket',0,b'\x00\x00\xE8\x23htons',0,b'\x00\x01\x1B\x23socket',0), + _struct_unions = ((b'\x00\x00\x01\x6A\x00\x00\x00\x03$1',b'\x00\x01\x66\x11DUMMYSTRUCTNAME',b'\x00\x00\x15\x11Pointer'),(b'\x00\x00\x01\x66\x00\x00\x00\x02$2',b'\x00\x00\x02\x11Offset',b'\x00\x00\x02\x11OffsetHigh'),(b'\x00\x00\x01\x6B\x00\x00\x00\x03$3',b'\x00\x01\x71\x11Byte',b'\x00\x01\x77\x11Word'),(b'\x00\x00\x01\x6C\x00\x00\x00\x01$4',b'\x00\x01\x67\x11',b'\x00\x00\x02\x11Value'),(b'\x00\x00\x01\x67\x00\x00\x00\x02$5',b'\x00\x00\x02\x13\x00\x00\x00\x1CZone',b'\x00\x00\x02\x13\x00\x00\x00\x04Level'),(b'\x00\x00\x01\x6D\x00\x00\x00\x03$6',b'\x00\x00\x02\x11sin6_scope_id',b'\x00\x01\x51\x11sin6_scope_struct'),(b'\x00\x00\x01\x6E\x00\x00\x00\x03$7',b'\x00\x01\x68\x11S_un_b',b'\x00\x01\x69\x11S_un_w',b'\x00\x00\x02\x11S_addr'),(b'\x00\x00\x01\x68\x00\x00\x00\x02$8',b'\x00\x01\x70\x11s_b1',b'\x00\x01\x70\x11s_b2',b'\x00\x01\x70\x11s_b3',b'\x00\x01\x70\x11s_b4'),(b'\x00\x00\x01\x69\x00\x00\x00\x02$9',b'\x00\x00\xE9\x11s_w1',b'\x00\x00\xE9\x11s_w2'),(b'\x00\x00\x01\x4D\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x02\x11dwProcessId',b'\x00\x00\x02\x11dwThreadId'),(b'\x00\x00\x01\x51\x00\x00\x00\x00$SCOPE_ID',b'\x00\x01\x6C\x11'),(b'\x00\x00\x01\x58\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x02\x11cb',b'\x00\x00\x2B\x11lpReserved',b'\x00\x00\x2B\x11lpDesktop',b'\x00\x00\x2B\x11lpTitle',b'\x00\x00\x02\x11dwX',b'\x00\x00\x02\x11dwY',b'\x00\x00\x02\x11dwXSize',b'\x00\x00\x02\x11dwYSize',b'\x00\x00\x02\x11dwXCountChars',b'\x00\x00\x02\x11dwYCountChars',b'\x00\x00\x02\x11dwFillAttribute',b'\x00\x00\x02\x11dwFlags',b'\x00\x00\xE9\x11wShowWindow',b'\x00\x00\xE9\x11cbReserved2',b'\x00\x01\x6F\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError'),(b'\x00\x00\x01\x47\x00\x00\x00\x02_GUID',b'\x00\x00\x02\x11Data1',b'\x00\x00\xE9\x11Data2',b'\x00\x00\xE9\x11Data3',b'\x00\x01\x73\x11Data4'),(b'\x00\x00\x01\x4C\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x02\x11Internal',b'\x00\x00\x02\x11InternalHigh',b'\x00\x01\x6A\x11DUMMYUNIONNAME',b'\x00\x00\x15\x11hEvent'),(b'\x00\x00\x01\x4F\x00\x00\x00\x02_PostCallbackData',b'\x00\x00\x15\x11hCompletionPort',b'\x00\x00\x26\x11Overlapped'),(b'\x00\x00\x01\x52\x00\x00\x00\x02_SECURITY_ATTRIBUTES',b'\x00\x00\x02\x11nLength',b'\x00\x00\x15\x11lpSecurityDescriptor',b'\x00\x00\x05\x11bInheritHandle'),(b'\x00\x00\x01\x59\x00\x00\x00\x02_WSABUF',b'\x00\x00\x02\x11len',b'\x00\x00\x2B\x11buf'),(b'\x00\x00\x01\x5B\x00\x00\x00\x02_WSAPROTOCOLCHAIN',b'\x00\x00\x05\x11ChainLen',b'\x00\x01\x75\x11ChainEntries'),(b'\x00\x00\x01\x5C\x00\x00\x00\x02_WSAPROTOCOL_INFOW',b'\x00\x00\x02\x11dwServiceFlags1',b'\x00\x00\x02\x11dwServiceFlags2',b'\x00\x00\x02\x11dwServiceFlags3',b'\x00\x00\x02\x11dwServiceFlags4',b'\x00\x00\x02\x11dwProviderFlags',b'\x00\x01\x47\x11ProviderId',b'\x00\x00\x02\x11dwCatalogEntryId',b'\x00\x01\x5B\x11ProtocolChain',b'\x00\x00\x05\x11iVersion',b'\x00\x00\x05\x11iAddressFamily',b'\x00\x00\x05\x11iMaxSockAddr',b'\x00\x00\x05\x11iMinSockAddr',b'\x00\x00\x05\x11iSocketType',b'\x00\x00\x05\x11iProtocol',b'\x00\x00\x05\x11iProtocolMaxOffset',b'\x00\x00\x05\x11iNetworkByteOrder',b'\x00\x00\x05\x11iSecurityScheme',b'\x00\x00\x02\x11dwMessageSize',b'\x00\x00\x02\x11dwProviderReserved',b'\x00\x01\x7A\x11szProtocol'),(b'\x00\x00\x01\x49\x00\x00\x00\x02in6_addr',b'\x00\x01\x6B\x11u'),(b'\x00\x00\x01\x4B\x00\x00\x00\x02in_addr',b'\x00\x01\x6E\x11S_un'),(b'\x00\x00\x01\x53\x00\x00\x00\x02sockaddr',b'\x00\x00\xE9\x11sa_family',b'\x00\x01\x5E\x11sa_data'),(b'\x00\x00\x01\x57\x00\x00\x00\x02sockaddr_in',b'\x00\x01\x65\x11sin_family',b'\x00\x00\xE9\x11sin_port',b'\x00\x01\x4B\x11sin_addr',b'\x00\x01\x60\x11sin_zero'),(b'\x00\x00\x01\x56\x00\x00\x00\x00sockaddr_in6',b'\x00\x00\xE9\x11sin6_family',b'\x00\x00\xE9\x11sin6_port',b'\x00\x00\x02\x11sin6_flowinfo',b'\x00\x01\x49\x11sin6_addr',b'\x00\x01\x6D\x11')), + _typenames = (b'\x00\x00\x00\xE9ADDRESS_FAMILY',b'\x00\x00\x01\x64AcceptExPtr',b'\x00\x00\x01\x63ConnectExPtr',b'\x00\x00\x01\x62DisconnectExPtr',b'\x00\x00\x01\x47GUID',b'\x00\x00\x01\x49IN6_ADDR',b'\x00\x00\x01\x4BINADDR',b'\x00\x00\x01\x62LPFN_DISCONNECTEX',b'\x00\x00\x01\x48LPIN6_ADDR',b'\x00\x00\x00\x26LPOVERLAPPED',b'\x00\x00\x00\x67LPOVERLAPPED_COMPLETION_ROUTINE',b'\x00\x00\x00\x34LPPROCESS_INFORMATION',b'\x00\x00\x01\x4ELPPostCallbackData',b'\x00\x00\x00\xFDLPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x19LPSOCKADDR',b'\x00\x00\x01\x54LPSOCKADDR_IN',b'\x00\x00\x01\x55LPSOCKADDR_IN6_LH',b'\x00\x00\x00\x33LPSTARTUPINFO',b'\x00\x00\x00\x62LPWSABUF',b'\x00\x00\x01\x5ALPWSAPROTOCOLCHAIN',b'\x00\x00\x00\xC1LPWSAPROTOCOL_INFOW',b'\x00\x00\x01\x4COVERLAPPED',b'\x00\x00\x01\x48PIN6_ADDR',b'\x00\x00\x01\x4APINADDR',b'\x00\x00\x01\x4DPROCESS_INFORMATION',b'\x00\x00\x01\x50PSCOPE_ID',b'\x00\x00\x00\xFDPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x19PSOCKADDR',b'\x00\x00\x01\x54PSOCKADDR_IN',b'\x00\x00\x01\x55PSOCKADDR_IN6_LH',b'\x00\x00\x01\x4FPostCallbackData',b'\x00\x00\x01\x51SCOPE_ID',b'\x00\x00\x01\x52SECURITY_ATTRIBUTES',b'\x00\x00\x01\x53SOCKADDR',b'\x00\x00\x01\x57SOCKADDR_IN',b'\x00\x00\x01\x56SOCKADDR_IN6_LH',b'\x00\x00\x00\x15SOCKET',b'\x00\x00\x01\x58STARTUPINFO',b'\x00\x00\x00\x3FWAITORTIMERCALLBACK',b'\x00\x00\x01\x59WSABUF',b'\x00\x00\x01\x5BWSAPROTOCOLCHAIN',b'\x00\x00\x01\x5CWSAPROTOCOL_INFOW',b'\x00\x00\x00\xE9wint_t'), ) diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py --- a/lib_pypy/_winapi.py +++ b/lib_pypy/_winapi.py @@ -17,6 +17,9 @@ NULL = _ffi.NULL +def GetLastError(): + return _kernel32.GetLastError() + # Now the _subprocess module implementation def _WinError(type=WindowsError): code, message = _ffi.getwinerror() @@ -99,12 +102,12 @@ bytes = _ffi.new('DWORD[1]') o = self.overlapped[0] if self.pending: - if _kernel32.CancelIoEx(o.handle, o.overlapped) & \ - self.GetOverlappedResult(o.handle, o.overlapped, _ffi.addressof(bytes), True): + if _kernel32.CancelIoEx(_int2handle(self.handle), self.overlapped) and \ + _kernel32.GetOverlappedResult(_int2handle(self.handle), self.overlapped, bytes, True): # The operation is no longer pending, nothing to do pass - else: - raise RuntimeError('deleting an overlapped struct with a pending operation not supported') + #else: + #raise RuntimeError('deleting an overlapped struct with a pending operation not supported') @property def event(self): @@ -133,22 +136,20 @@ tempbuffer = _ffi.new("CHAR[]", transferred[0]) _ffi.memmove(tempbuffer, self.readbuffer, transferred[0]) self.readbuffer = tempbuffer - return None return transferred[0], err def getbuffer(self): if not self.completed: raise ValueError("can't get read buffer before GetOverlappedResult() " "signals the operation completed") - return self.readbuffer + return _ffi.buffer(self.readbuffer) def cancel(self): ret = True if self.pending: ret = _kernel32.CancelIoEx(_int2handle(self.handle), self.overlapped) if not ret and _kernel32.GetLastError() != ERROR_NOT_FOUND: - # In CPython SetExcFromWindowsErr is called here. - SetFromWindowsErr(0) + return _WinError(IOError) self.pending = 0 return None @@ -202,12 +203,15 @@ overlapped = Overlapped(handle) if not overlapped: return _ffi.NULL - overlapped.writebuffer = _ffi.new("CHAR[]", bytes(buffer)) + overlapped.writebuffer = bytes(buffer) buf = overlapped.writebuffer else: buf = _ffi.new("CHAR[]", bytes(buffer)) - ret = _kernel32.WriteFile(_int2handle(handle), buf , len(buf), written, overlapped.overlapped) + if use_overlapped: + ret = _kernel32.WriteFile(_int2handle(handle), buf , len(buf), written, overlapped.overlapped) + else: + ret = _kernel32.WriteFile(_int2handle(handle), buf , len(buf), written, _ffi.NULL) if ret: err = 0 @@ -220,8 +224,6 @@ overlapped.pending = 1 elif err != ERROR_MORE_DATA: return _WinError(IOError) - - assert written == len(overlapped.writebuffer) return overlapped, err if not ret: @@ -229,9 +231,9 @@ # The whole of the buffer should have been written # otherwise this function call has been be successful - assert written == len(buf) + assert written[0] == len(buf) - return written, err + return written[0], err def ConnectNamedPipe(handle, overlapped=False): @@ -348,16 +350,17 @@ # Not sure what that is doing currently. SetFromWindowsErr(0) + assert nread == len(buf) # if (_PyBytes_Resize(&buf, nread)) # return NULL; - return buf, navail, nleft + return buf, navail[0], nleft[0] else: ret = _kernel32.PeekNamedPipe(_int2handle(handle), _ffi.NULL, 0, _ffi.NULL, navail, nleft) if not ret: # In CPython SetExcFromWindowsErr is called here. # Not sure what that is doing currently. SetFromWindowsErr(0) - return navail, nleft + return navail[0], nleft[0] def WaitForSingleObject(handle, milliseconds): # CPython: the first argument is expected to be an integer. @@ -366,6 +369,14 @@ raise _WinError() return res + +def WaitNamedPipe(namedpipe, milliseconds): + namedpipe = _ffi.new("CHAR[]", namedpipe.encode("ascii", "ignore")) + res = _kernel32.WaitNamedPipeA(namedpipe, milliseconds) + if res < 0: + raise SetFromWindowsErr(0) + + def WaitForMultipleObjects(handle_sequence, waitflag, milliseconds): if len(handle_sequence) > MAXIMUM_WAIT_OBJECTS: return None @@ -453,15 +464,19 @@ ERROR_SUCCESS = 0 ERROR_NETNAME_DELETED = 64 ERROR_BROKEN_PIPE = 109 -ERROR_PIPE_BUSY = 231 +ERROR_SEM_TIMEOUT = 121 +ERROR_PIPE_BUSY = 231 +ERROR_NO_DATA = 232 ERROR_MORE_DATA = 234 ERROR_PIPE_CONNECTED = 535 ERROR_OPERATION_ABORTED = 995 ERROR_IO_INCOMPLETE = 996 ERROR_IO_PENDING = 997 +ERROR_NOT_FOUND = 1168 ERROR_CONNECTION_REFUSED = 1225 ERROR_CONNECTION_ABORTED = 1236 + PIPE_ACCESS_INBOUND = 0x00000001 PIPE_ACCESS_OUTBOUND = 0x00000002 PIPE_ACCESS_DUPLEX = 0x00000003 From pypy.commits at gmail.com Mon Apr 22 05:18:39 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 22 Apr 2019 02:18:39 -0700 (PDT) Subject: [pypy-commit] pypy arm64: start passing call tests Message-ID: <5cbd86ef.1c69fb81.93664.0996@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96529:1830218346d5 Date: 2019-04-20 11:54 +0000 http://bitbucket.org/pypy/pypy/changeset/1830218346d5/ Log: start passing call tests diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -442,20 +442,42 @@ baseofs = self.cpu.get_baseofs_of_frame_field() self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) + def _reload_frame_if_necessary(self, mc): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + YYY + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(r.ip.value, rst) + self.load_reg(mc, r.ip, r.ip) + self.load_reg(mc, r.fp, r.ip, ofs=-WORD) + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + if gcrootmap and wbdescr: + YYY + # frame never uses card marking, so we enforce this is not + # an array + self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False, + is_frame=True) + def generate_quick_failure(self, guardtok): startpos = self.mc.currpos() faildescrindex, target = self.store_info_on_descr(startpos, guardtok) self.load_from_gc_table(r.ip0.value, faildescrindex) self.store_reg(self.mc, r.ip0, r.fp, WORD) - self.push_gcmap(self.mc, gcmap=guardtok.gcmap, ofs=0) + self.push_gcmap(self.mc, gcmap=guardtok.gcmap) self.mc.BL(target) return startpos - def push_gcmap(self, mc, gcmap, ofs): + def push_gcmap(self, mc, gcmap): + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') ptr = rffi.cast(lltype.Signed, gcmap) mc.gen_load_int(r.ip0.value, ptr) self.store_reg(mc, r.ip0, r.fp, ofs) + def pop_gcmap(self, mc): + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.gen_load_int(r.ip0.value, 0) + self.store_reg(mc, r.ip0, r.fp, ofs) + def write_pending_failure_recoveries(self): for tok in self.pending_guards: #generate the exit stub and the encoded representation diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -203,9 +203,14 @@ self.write32((base << 24) | (imm << 5) | cond) def BL(self, target): + # XXX use the IMM version if close enough target = rffi.cast(lltype.Signed, target) self.gen_load_int_full(r.ip0.value, target) - self.BR(r.ip0.value) + self.BLR(r.ip0.value) + + def BLR(self, reg): + base = 0b1101011000111111000000 + self.write32((base << 10) | (reg << 5)) def BR(self, reg): base = 0b1101011000011111000000 diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -2,6 +2,7 @@ from rpython.jit.metainterp.history import (AbstractFailDescr, ConstInt, INT, FLOAT, REF) from rpython.jit.backend.aarch64 import registers as r +from rpython.jit.backend.aarch64.callbuilder import Aarch64CallBuilder from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler @@ -190,6 +191,44 @@ self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs) emit_guard_op_guard_overflow = emit_guard_op_guard_false + def _genop_call(self, op, arglocs): + return self._emit_call(op, arglocs) + emit_op_call_i = _genop_call + emit_op_call_r = _genop_call + emit_op_call_f = _genop_call + emit_op_call_n = _genop_call + + def _emit_call(self, op, arglocs, is_call_release_gil=False): + # args = [resloc, size, sign, args...] + from rpython.jit.backend.llsupport.descr import CallDescr + + func_index = 3 + is_call_release_gil + cb = Aarch64CallBuilder(self, arglocs[func_index], + arglocs[func_index+1:], arglocs[0]) + + descr = op.getdescr() + assert isinstance(descr, CallDescr) + cb.callconv = descr.get_call_conv() + cb.argtypes = descr.get_arg_types() + cb.restype = descr.get_result_type() + sizeloc = arglocs[1] + assert sizeloc.is_imm() + cb.ressize = sizeloc.value + signloc = arglocs[2] + assert signloc.is_imm() + cb.ressign = signloc.value + + if is_call_release_gil: + saveerrloc = arglocs[3] + assert saveerrloc.is_imm() + cb.emit_call_release_gil(saveerrloc.value) + else: + effectinfo = descr.get_extra_info() + if effectinfo is None or effectinfo.check_can_collect(): + cb.emit() + else: + cb.emit_no_collect() + def load_condition_into_cc(self, loc): if not loc.is_core_reg(): assert loc.is_stack() diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -17,6 +17,8 @@ from rpython.jit.backend.arm.jump import remap_frame_layout_mixed from rpython.jit.backend.aarch64.locations import imm from rpython.jit.backend.llsupport.gcmap import allocate_gcmap +from rpython.jit.backend.llsupport.descr import CallDescr +from rpython.jit.codewriter.effectinfo import EffectInfo @@ -80,6 +82,8 @@ forbidden_vars, selected_reg) + + class VFPRegisterManager(ARMRegisterManager): all_regs = r.all_vfp_regs box_types = [FLOAT] @@ -94,14 +98,6 @@ def __init__(self, longevity, frame_manager=None, assembler=None): RegisterManager.__init__(self, longevity, frame_manager, assembler) - def after_call(self, v): - """ Adjust registers according to the result of the call, - which is in variable v. - """ - self._check_type(v) - reg = self.force_allocate_reg(v, selected_reg=r.d0) - return reg - def get_scratch_reg(self, type=FLOAT, forbidden_vars=[], selected_reg=None): assert type == FLOAT # for now box = TempFloat() @@ -122,7 +118,7 @@ RegisterManager.__init__(self, longevity, frame_manager, assembler) def call_result_location(self, v): - return r.r0 + return r.x0 def convert_to_imm(self, c): if isinstance(c, ConstInt): @@ -414,6 +410,92 @@ prepare_op_int_neg = prepare_unary prepare_op_int_invert = prepare_unary + def _prepare_op_call(self, op): + calldescr = op.getdescr() + assert calldescr is not None + effectinfo = calldescr.get_extra_info() + if effectinfo is not None: + oopspecindex = effectinfo.oopspecindex + if oopspecindex in (EffectInfo.OS_LLONG_ADD, + EffectInfo.OS_LLONG_SUB, + EffectInfo.OS_LLONG_AND, + EffectInfo.OS_LLONG_OR, + EffectInfo.OS_LLONG_XOR): + if self.cpu.cpuinfo.neon: + args = self._prepare_llong_binop_xx(op, fcond) + self.perform_extra(op, args, fcond) + return + elif oopspecindex == EffectInfo.OS_LLONG_TO_INT: + args = self._prepare_llong_to_int(op, fcond) + self.perform_extra(op, args, fcond) + return + elif oopspecindex == EffectInfo.OS_MATH_SQRT: + args = self._prepare_op_math_sqrt(op, fcond) + self.perform_extra(op, args, fcond) + return + elif oopspecindex == EffectInfo.OS_THREADLOCALREF_GET: + args = self._prepare_threadlocalref_get(op, fcond) + self.perform_extra(op, args, fcond) + return + #elif oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP: + # ... + return self._prepare_call(op) + + prepare_op_call_i = _prepare_op_call + prepare_op_call_r = _prepare_op_call + prepare_op_call_f = _prepare_op_call + prepare_op_call_n = _prepare_op_call + + def _prepare_call(self, op, save_all_regs=False, first_arg_index=1): + args = [None] * (op.numargs() + 3) + calldescr = op.getdescr() + assert isinstance(calldescr, CallDescr) + assert len(calldescr.arg_classes) == op.numargs() - first_arg_index + + for i in range(op.numargs()): + args[i + 3] = self.loc(op.getarg(i)) + + size = calldescr.get_result_size() + sign = calldescr.is_result_signed() + if sign: + sign_loc = imm(1) + else: + sign_loc = imm(0) + args[1] = imm(size) + args[2] = sign_loc + + effectinfo = calldescr.get_extra_info() + if save_all_regs: + gc_level = 2 + elif effectinfo is None or effectinfo.check_can_collect(): + gc_level = 1 + else: + gc_level = 0 + + args[0] = self._call(op, args, gc_level) + return args + + def _call(self, op, arglocs, gc_level): + # spill variables that need to be saved around calls: + # gc_level == 0: callee cannot invoke the GC + # gc_level == 1: can invoke GC, save all regs that contain pointers + # gc_level == 2: can force, save all regs + save_all_regs = gc_level == 2 + self.vfprm.before_call(save_all_regs=save_all_regs) + if gc_level == 1 and self.cpu.gc_ll_descr.gcrootmap: + save_all_regs = 2 + self.rm.before_call(save_all_regs=save_all_regs) + resloc = self.after_call(op) + return resloc + + def after_call(self, v): + if v.type == 'v': + return + if v.type == FLOAT: + return self.vfprm.after_call(v) + else: + return self.rm.after_call(v) + def prepare_op_label(self, op): descr = op.getdescr() assert isinstance(descr, TargetToken) From pypy.commits at gmail.com Mon Apr 22 05:18:41 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 22 Apr 2019 02:18:41 -0700 (PDT) Subject: [pypy-commit] pypy arm64: LSL_ri & ASR_ri Message-ID: <5cbd86f1.1c69fb81.da132.4193@mx.google.com> Author: fijal Branch: arm64 Changeset: r96530:1fe592cd9f4d Date: 2019-04-22 11:17 +0200 http://bitbucket.org/pypy/pypy/changeset/1fe592cd9f4d/ Log: LSL_ri & ASR_ri diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -10,6 +10,14 @@ PC_OFFSET = 0 # XXX class AbstractAarch64Builder(object): + # just copied some values from https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a + immr_imms = { + 32: (0b111011, 0b000000), + 56: (0b111101, 0b000010), + 48: (0b111100, 0b000001), + 16: (0b111100, 0b000000), + } + def write32(self, word): self.writechar(chr(word & 0xFF)) self.writechar(chr((word >> 8) & 0xFF)) @@ -135,10 +143,20 @@ base = 0b10011010110 self.write32((base << 21) | (rm << 16) | (0b001000 << 10) | (rn << 5) | rd) + def LSL_ri(self, rd, rn, shift): + immr, imms = self.immr_imms[shift] + base = 0b1101001101 + self.write32((base << 22) | (immr << 16) | (imms << 10) | (rn << 5) | rd) + def ASR_rr(self, rd, rn, rm): base = 0b10011010110 self.write32((base << 21) | (rm << 16) | (0b001010 << 10) | (rn << 5) | rd) + def ASR_ri(self, rd, rn, shift): + immr, imms = self.immr_imms[shift] + base = 0b1001001101 + self.write32((base << 22) | (immr << 16) | (imms << 10) | (rn << 5) | rd) + def LSR_rr(self, rd, rn, rm): base = 0b10011010110 self.write32((base << 21) | (rm << 16) | (0b001001 << 10) | (rn << 5) | rd) From pypy.commits at gmail.com Mon Apr 22 05:21:42 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 22 Apr 2019 02:21:42 -0700 (PDT) Subject: [pypy-commit] pypy arm64: make tests more consistent on 64bit and test more combinations of types Message-ID: <5cbd87a6.1c69fb81.c0b96.180a@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96531:03aa7d305b2f Date: 2019-04-22 09:20 +0000 http://bitbucket.org/pypy/pypy/changeset/03aa7d305b2f/ Log: make tests more consistent on 64bit and test more combinations of types diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -542,8 +542,10 @@ return chr(ord(c) + ord(c1)) functions = [ - (func_int, lltype.Signed, types.sint, 655360, 655360), - (func_int, lltype.Signed, types.sint, 655360, -293999429), + (func_int, lltype.Signed, types.slong, 655360, 655360), + (func_int, lltype.Signed, types.slong, 655360, -293999429), + (func_int, rffi.INT, types.sint, 655360, 655360), + (func_int, rffi.INT, types.sint, 655360, -293999429), (func_int, rffi.SHORT, types.sint16, 1213, 1213), (func_int, rffi.SHORT, types.sint16, 1213, -12020), (func_char, lltype.Char, types.uchar, 12, 12), From pypy.commits at gmail.com Mon Apr 22 06:23:46 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 22 Apr 2019 03:23:46 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: issue #2996: a first bug found and fixed, but there is more Message-ID: <5cbd9632.1c69fb81.dd37c.18ce@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96532:363063d2f12b Date: 2019-04-22 11:49 +0200 http://bitbucket.org/pypy/pypy/changeset/363063d2f12b/ Log: issue #2996: a first bug found and fixed, but there is more diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -58,8 +58,9 @@ assert argcount >= 0 # annotator hint assert kwonlyargcount >= 0 argnames = list(varnames[:argcount]) - if argcount < len(varnames): + if kwonlyargcount > 0: kwonlyargs = list(varnames[argcount:argcount + kwonlyargcount]) + argcount += kwonlyargcount else: kwonlyargs = None if code.co_flags & CO_VARARGS: @@ -68,7 +69,7 @@ else: varargname = None if code.co_flags & CO_VARKEYWORDS: - kwargname = code.co_varnames[argcount + kwonlyargcount] + kwargname = code.co_varnames[argcount] else: kwargname = None return Signature(argnames, varargname, kwargname, kwonlyargs) diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py --- a/pypy/interpreter/test/test_compiler.py +++ b/pypy/interpreter/test/test_compiler.py @@ -824,6 +824,13 @@ sig = cpython_code_signature(co) assert sig == Signature(['a', 'b'], None, 'kwargs', ['m', 'n']) + # a variant with varargname, which was buggy before issue2996 + snippet = 'def f(*args, offset=42): pass' + containing_co = self.compiler.compile(snippet, '', 'single', 0) + co = find_func(containing_co) + sig = cpython_code_signature(co) + assert sig == Signature([], 'args', None, ['offset']) + class AppTestCompiler(object): From pypy.commits at gmail.com Mon Apr 22 06:23:48 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 22 Apr 2019 03:23:48 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Issue #2996 (argument parsing issue) Message-ID: <5cbd9634.1c69fb81.df112.2c30@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96533:bdfe0ecd439b Date: 2019-04-22 12:23 +0200 http://bitbucket.org/pypy/pypy/changeset/bdfe0ecd439b/ Log: Issue #2996 (argument parsing issue) Test and fix diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -180,14 +180,17 @@ too_many_args = False # put the special w_firstarg into the scope, if it exists + upfront = 0 + args_w = self.arguments_w if w_firstarg is not None: - upfront = 1 if co_argcount > 0: scope_w[0] = w_firstarg - else: - upfront = 0 + upfront = 1 + else: + # ugh, this is a call to a method 'def meth(*args)', maybe + # (see test_issue2996_*). Fall-back solution... + args_w = [w_firstarg] + args_w - args_w = self.arguments_w num_args = len(args_w) avail = num_args + upfront @@ -210,11 +213,8 @@ # collect extra positional arguments into the *vararg if signature.has_vararg(): args_left = co_argcount - upfront - if args_left < 0: # check required by rpython - starargs_w = [w_firstarg] - if num_args: - starargs_w = starargs_w + args_w - elif num_args > args_left: + assert args_left >= 0 # check required by rpython + if num_args > args_left: starargs_w = args_w[args_left:] else: starargs_w = [] diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -923,3 +923,18 @@ def test(**kwargs): return kwargs assert test(**q) == {"foo": "bar"} + + def test_issue2996_1(self): """ + class Class: + def method(*args, a_parameter=None, **kwargs): + pass + Class().method(**{'a_parameter': 4}) + """ + + def test_issue2996_2(self): """ + class Foo: + def methhh(*args, offset=42): + return args, offset + foo = Foo() + assert foo.methhh(**{}) == ((foo,), 42) + """ From pypy.commits at gmail.com Mon Apr 22 06:25:57 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 22 Apr 2019 03:25:57 -0700 (PDT) Subject: [pypy-commit] pypy arm64: more calling Message-ID: <5cbd96b5.1c69fb81.50f98.58f1@mx.google.com> Author: fijal Branch: arm64 Changeset: r96534:26809d94a756 Date: 2019-04-22 12:25 +0200 http://bitbucket.org/pypy/pypy/changeset/26809d94a756/ Log: more calling diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -717,10 +717,23 @@ else: XXX + def _mov_imm_to_loc(self, prev_loc, loc): + assert loc.is_core_reg() + self.mc.gen_load_int(loc.value, prev_loc.value) + def new_stack_loc(self, i, tp): base_ofs = self.cpu.get_baseofs_of_frame_field() return StackLocation(i, get_fp_offset(base_ofs, i), tp) + def mov_loc_to_raw_stack(self, loc, pos): + if loc.is_core_reg(): + self.mc.STR_ri(loc.value, r.sp.value, pos) + elif loc.is_stack(): + self.mc.LDR_ri(r.ip0.value, r.fp.value, loc.value) + self.mc.STR_ri(r.ip0.value, r.sp.value, pos) + else: + assert False, "wrong loc" + def regalloc_mov(self, prev_loc, loc): """Moves a value from a previous location to some other location""" if prev_loc.is_imm(): @@ -733,8 +746,6 @@ self._mov_imm_float_to_loc(prev_loc, loc) elif prev_loc.is_vfp_reg(): self._mov_vfp_reg_to_loc(prev_loc, loc) - elif prev_loc.is_raw_sp(): - self._mov_raw_sp_to_loc(prev_loc, loc) else: assert 0, 'unsupported case' mov_loc_loc = regalloc_mov diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -11,13 +11,6 @@ class AbstractAarch64Builder(object): # just copied some values from https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a - immr_imms = { - 32: (0b111011, 0b000000), - 56: (0b111101, 0b000010), - 48: (0b111100, 0b000001), - 16: (0b111100, 0b000000), - } - def write32(self, word): self.writechar(chr(word & 0xFF)) self.writechar(chr((word >> 8) & 0xFF)) @@ -139,12 +132,22 @@ base = 0b10001010000 self.write32((base << 21) | (rm << 16) | (rn << 5) | rd) + def AND_ri(self, rd, rn, immed): + assert immed == 0xFF # just one value for now, don't feel like + # understanding IMMR/IMMS quite yet + base = 0b1001001001 + immr = 0b000000 + imms = 0b000111 + self.write32((base << 22) | (immr << 16) | (imms << 10) | (rn << 5) | rd) + def LSL_rr(self, rd, rn, rm): base = 0b10011010110 self.write32((base << 21) | (rm << 16) | (0b001000 << 10) | (rn << 5) | rd) def LSL_ri(self, rd, rn, shift): - immr, imms = self.immr_imms[shift] + assert 0 <= shift <= 63 + immr = 64 - shift + imms = immr - 1 base = 0b1101001101 self.write32((base << 22) | (immr << 16) | (imms << 10) | (rn << 5) | rd) @@ -153,10 +156,19 @@ self.write32((base << 21) | (rm << 16) | (0b001010 << 10) | (rn << 5) | rd) def ASR_ri(self, rd, rn, shift): - immr, imms = self.immr_imms[shift] + assert 0 <= shift <= 63 + imms = 0b111111 + immr = shift base = 0b1001001101 self.write32((base << 22) | (immr << 16) | (imms << 10) | (rn << 5) | rd) + def LSR_ri(self, rd, rn, shift): + assert 0 <= shift <= 63 + imms = 0b111111 + immr = shift + base = 0b1101001101 + self.write32((base << 22) | (immr << 16) | (imms << 10) | (rn << 5) | rd) + def LSR_rr(self, rd, rn, rm): base = 0b10011010110 self.write32((base << 21) | (rm << 16) | (0b001001 << 10) | (rn << 5) | rd) From pypy.commits at gmail.com Mon Apr 22 07:33:27 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 22 Apr 2019 04:33:27 -0700 (PDT) Subject: [pypy-commit] pypy arm64: enough to start passing basic field tests Message-ID: <5cbda687.1c69fb81.cb475.e643@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96535:682a0e1492d9 Date: 2019-04-22 11:32 +0000 http://bitbucket.org/pypy/pypy/changeset/682a0e1492d9/ Log: enough to start passing basic field tests diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -10,7 +10,6 @@ PC_OFFSET = 0 # XXX class AbstractAarch64Builder(object): - # just copied some values from https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a def write32(self, word): self.writechar(chr(word & 0xFF)) self.writechar(chr((word >> 8) & 0xFF)) @@ -41,6 +40,18 @@ self.write32((base << 22) | ((0x7F & (offset >> 3)) << 15) | (reg2 << 10) | (rn << 5) | reg1) + def STR_size_rr(self, scale, rt, rn, rm): + base = 0b111000001 + assert 0 <= scale <= 3 + self.wirte32((scale << 30) | (base << 21) | (rm << 16) | (0b11 << 13) | + (0b010 << 10) | (rn << 5) | rt) + + def STR_size_ri(self, scale, rt, rn, imm): + assert 0 <= imm < 4096 + assert 0 <= scale <= 3 + base = 0b11100100 + self.write32((scale << 30) | (base << 22) | (imm >> scale << 10) | (rn << 5) | rt) + def MOV_rr(self, rd, rn): self.ORR_rr(rd, r.xzr.value, rn) @@ -100,6 +111,18 @@ assert 0 <= immed <= 1<<15 assert immed & 0x7 == 0 self.write32((base << 22) | (immed >> 3 << 10) | (rn << 5) | rt) + + def LDR_rr(self, rt, rn, rm): + xxx + + def LDR_size_ri(self, size, rt, rn, ofs): + assert 0 <= size <= 3 + assert 0 <= ofs <= 4096 + base = 0b11100101 + self.write32((size << 30) | (base << 22) | (ofs >> size << 10) | (rn << 5) | rt) + + def LDR_size_rr(self, size, rt, rn, rm): + xxx def LDR_r_literal(self, rt, offset): base = 0b01011000 @@ -236,9 +259,9 @@ # XXX use the IMM version if close enough target = rffi.cast(lltype.Signed, target) self.gen_load_int_full(r.ip0.value, target) - self.BLR(r.ip0.value) + self.BLR_r(r.ip0.value) - def BLR(self, reg): + def BLR_r(self, reg): base = 0b1101011000111111000000 self.write32((base << 10) | (reg << 5)) diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -5,8 +5,10 @@ from rpython.jit.backend.aarch64.callbuilder import Aarch64CallBuilder from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE +from rpython.jit.backend.aarch64.locations import imm from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler from rpython.jit.backend.llsupport.gcmap import allocate_gcmap +from rpython.jit.backend.llsupport.regalloc import get_scale from rpython.jit.metainterp.history import TargetToken def gen_comp_op(name, flag): @@ -152,6 +154,69 @@ self.mc.ADD_ri(value_loc.value, value_loc.value, 1) self.mc.STR_ri(value_loc.value, base_loc.value, 0) + # -------------------------------- fields ------------------------------- + + def emit_op_gc_store(self, op, arglocs): + value_loc, base_loc, ofs_loc, size_loc = arglocs + scale = get_scale(size_loc.value) + self._write_to_mem(value_loc, base_loc, ofs_loc, imm(scale)) + + def _emit_op_gc_load(self, op, arglocs): + base_loc, ofs_loc, res_loc, nsize_loc = arglocs + nsize = nsize_loc.value + signed = (nsize < 0) + scale = get_scale(abs(nsize)) + self._load_from_mem(res_loc, base_loc, ofs_loc, imm(scale), signed) + + emit_op_gc_load_i = _emit_op_gc_load + emit_op_gc_load_r = _emit_op_gc_load + emit_op_gc_load_f = _emit_op_gc_load + + def _write_to_mem(self, value_loc, base_loc, ofs_loc, scale): + # Write a value of size '1 << scale' at the address + # 'base_ofs + ofs_loc'. Note that 'scale' is not used to scale + # the offset! + assert base_loc.is_core_reg() + if scale.value == 3: + # WORD size + if ofs_loc.is_imm(): + self.mc.STR_ri(value_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.STR_rr(value_loc.value, base_loc.value, + ofs_loc.value) + else: + if ofs_loc.is_imm(): + self.mc.STR_size_ri(scale.value, value_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.STR_size_rr(scale.value, value_loc.value, base_loc.value, + ofs_loc.value) + + def _load_from_mem(self, res_loc, base_loc, ofs_loc, scale, + signed=False): + # Load a value of '1 << scale' bytes, from the memory location + # 'base_loc + ofs_loc'. Note that 'scale' is not used to scale + # the offset! + # + if scale.value == 3: + # WORD + if ofs_loc.is_imm(): + self.mc.LDR_ri(res_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.LDR_rr(res_loc.value, base_loc.value, + ofs_loc.value) + else: + if ofs_loc.is_imm(): + self.mc.LDR_size_ri(scale.value, res_loc.value, base_loc.value, + ofs_loc.value) + else: + self.mc.LDR_size_rr(scale.value, res_loc.value, base_loc.value, + ofs_loc.value) + + # -------------------------------- guard -------------------------------- + def build_guard_token(self, op, frame_depth, arglocs, offset, fcond): descr = op.getdescr() assert isinstance(descr, AbstractFailDescr) @@ -191,6 +256,8 @@ self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs) emit_guard_op_guard_overflow = emit_guard_op_guard_false + # ----------------------------- call ------------------------------ + def _genop_call(self, op, arglocs): return self._emit_call(op, arglocs) emit_op_call_i = _genop_call @@ -272,11 +339,11 @@ gcmap = self._finish_gcmap else: gcmap = self.gcmap_for_finish - self.push_gcmap(self.mc, gcmap, store=True) + self.push_gcmap(self.mc, gcmap) elif self._finish_gcmap: # we're returning with a guard_not_forced_2 gcmap = self._finish_gcmap - self.push_gcmap(self.mc, gcmap, store=True) + self.push_gcmap(self.mc, gcmap) else: # note that the 0 here is redundant, but I would rather # keep that one and kill all the others diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -410,6 +410,42 @@ prepare_op_int_neg = prepare_unary prepare_op_int_invert = prepare_unary + # --------------------------------- fields -------------------------- + + def prepare_op_gc_store(self, op): + boxes = op.getarglist() + base_loc = self.make_sure_var_in_reg(boxes[0], boxes) + ofs = boxes[1].getint() + value_loc = self.make_sure_var_in_reg(boxes[2], boxes) + size = boxes[3].getint() + if check_imm_arg(ofs): + ofs_loc = imm(ofs) + else: + ofs_loc = r.ip1 + self.assembler.load(ofs_loc, imm(ofs)) + return [value_loc, base_loc, ofs_loc, imm(size)] + + def _prepare_op_gc_load(self, op): + a0 = op.getarg(0) + ofs = op.getarg(1).getint() + nsize = op.getarg(2).getint() # negative for "signed" + base_loc = self.make_sure_var_in_reg(a0) + immofs = imm(ofs) + if check_imm_arg(ofs): + ofs_loc = immofs + else: + ofs_loc = r.ip1 + self.assembler.load(ofs_loc, immofs) + self.possibly_free_vars_for_op(op) + res_loc = self.force_allocate_reg(op) + return [base_loc, ofs_loc, res_loc, imm(nsize)] + + prepare_op_gc_load_i = _prepare_op_gc_load + prepare_op_gc_load_r = _prepare_op_gc_load + prepare_op_gc_load_f = _prepare_op_gc_load + + # --------------------------------- call ---------------------------- + def _prepare_op_call(self, op): calldescr = op.getdescr() assert calldescr is not None diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -709,6 +709,7 @@ shortdescr = self.cpu.fielddescrof(self.S, 'short') self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(250)], 'void', descr=fielddescr2) + self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(133)], 'void', descr=fielddescr1) self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(1331)], From pypy.commits at gmail.com Mon Apr 22 12:11:48 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 22 Apr 2019 09:11:48 -0700 (PDT) Subject: [pypy-commit] pypy issue2996: close branch, fixed directly on py3.6 Message-ID: <5cbde7c4.1c69fb81.bb309.b13d@mx.google.com> Author: Matti Picus Branch: issue2996 Changeset: r96536:ab27979d22ca Date: 2019-04-22 19:10 +0300 http://bitbucket.org/pypy/pypy/changeset/ab27979d22ca/ Log: close branch, fixed directly on py3.6 From pypy.commits at gmail.com Mon Apr 22 14:25:49 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 22 Apr 2019 11:25:49 -0700 (PDT) Subject: [pypy-commit] pypy default: mutiple flush calls do not raise on cpython Message-ID: <5cbe072d.1c69fb81.4f895.d939@mx.google.com> Author: Matti Picus Branch: Changeset: r96537:d0a7535c8be7 Date: 2019-04-22 21:19 +0300 http://bitbucket.org/pypy/pypy/changeset/d0a7535c8be7/ Log: mutiple flush calls do not raise on cpython diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py --- a/pypy/module/zlib/interp_zlib.py +++ b/pypy/module/zlib/interp_zlib.py @@ -352,8 +352,7 @@ raise oefmt(space.w_ValueError, "length must be greater than zero") if not self.stream: - raise zlib_error(space, - "compressor object already flushed") + return space.newbytes('') data = self.unconsumed_tail try: self.lock() diff --git a/pypy/module/zlib/test/test_zlib.py b/pypy/module/zlib/test/test_zlib.py --- a/pypy/module/zlib/test/test_zlib.py +++ b/pypy/module/zlib/test/test_zlib.py @@ -363,4 +363,5 @@ dco = zlib.decompressobj() dco.decompress(x) dco.flush() - raises(self.zlib.error, dco.flush) + # multiple flush calls should not raise + dco.flush() From pypy.commits at gmail.com Mon Apr 22 14:25:51 2019 From: pypy.commits at gmail.com (mattip) Date: Mon, 22 Apr 2019 11:25:51 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: merge default into branch Message-ID: <5cbe072f.1c69fb81.93e9a.fe8a@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96538:92b1713ab818 Date: 2019-04-22 21:24 +0300 http://bitbucket.org/pypy/pypy/changeset/92b1713ab818/ Log: merge default into branch diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -10,10 +10,6 @@ 32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1 10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0 9c4588d731b7fe0b08669bd732c2b676cb0a8233 release-2.5.1 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0 f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0 @@ -24,17 +20,10 @@ b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2 40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 -40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 d7724c0a5700b895a47de44074cdf5fd659a988f RevDB-pypy2.7-v5.4.1 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0 e90317857d27917bf840caf675832292ee070510 RevDB-pypy2.7-v5.6.1 @@ -45,33 +34,20 @@ 2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1 c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0 a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0 0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0 3f6eaa010fce78cc7973bdc1dfdb95970f08fed2 release-pypy3.5-v5.10.1 ab0b9caf307db6592905a80b8faffd69b39005b8 release-pypy2.7-v6.0.0 fdd60ed87e941677e8ea11acf9f1819466521bf2 release-pypy3.5-v6.0.0 9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 -9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 c8805ee6d7846ca2722b106eeaa2f128c699aba3 release-pypy2.7-v7.0.0 -1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 -bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 -bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 -6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 -6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 -7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 -7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 +784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1 +8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1 + diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -95,7 +95,9 @@ There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times -if the object is resurrected and dies again. The ``__del__`` methods are +if the object is resurrected and dies again (at least it is reliably so in +older CPythons; newer CPythons try to call destructors not more than once, +but there are counter-examples). The ``__del__`` methods are called in "the right" order if they are on objects pointing to each other, as in CPython, but unlike CPython, if there is a dead cycle of objects referencing each other, their ``__del__`` methods are called anyway; diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-v7.1.1.rst release-v7.1.0.rst release-v7.0.0.rst release-v6.0.0.rst diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-pypy2-7.1.0.rst whatsnew-pypy2-7.0.0.rst whatsnew-pypy2-6.0.0.rst whatsnew-pypy2-5.10.0.rst diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst --- a/pypy/doc/release-v7.1.1.rst +++ b/pypy/doc/release-v7.1.1.rst @@ -68,10 +68,14 @@ Changelog ========= -Changes shared across versions -* improve performance of ``u''.append`` +Changes shared across versions: + +* Improve performance of ``u''.append`` + * Prevent a crash in ``zlib`` when flushing a closed stream -* Fix a few corener cases when encountering unicode values above 0x110000 + +* Fix a few corner cases when encountering unicode values above 0x110000 + * Teach the JIT how to handle very large constant lists, sets, or dicts * Fix building on ARM32 (issue 2984_) * Fix a bug in register assignment in ARM32 @@ -81,9 +85,9 @@ * Fix memoryviews of ctype structures with padding, (cpython issue 32780_) * CFFI updated to as-yet-unreleased 1.12.3 -Python 3.6 only +Python 3.6 only: -* On win32, override some ``errno.E*`` values that were added to MSVC in v2010 +* Override some ``errno.E*`` values that were added to MSVC in v2010 so that ``errno.E* == errno.WSAE*`` as in CPython * Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the AST level) diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -94,8 +94,8 @@ lgt = min(arr1.len, arr2.len) for i in range(lgt): arr_eq_driver.jit_merge_point(comp_func=comp_op) - w_elem1 = arr1.w_getitem(space, i) - w_elem2 = arr2.w_getitem(space, i) + w_elem1 = arr1.w_getitem(space, i, integer_instead_of_char=True) + w_elem2 = arr2.w_getitem(space, i, integer_instead_of_char=True) if comp_op == EQ: res = space.eq_w(w_elem1, w_elem2) if not res: @@ -1142,10 +1142,11 @@ else: self.fromsequence(w_iterable) - def w_getitem(self, space, idx): + def w_getitem(self, space, idx, integer_instead_of_char=False): item = self.get_buffer()[idx] keepalive_until_here(self) - if mytype.typecode in 'bBhHil': + if mytype.typecode in 'bBhHil' or ( + integer_instead_of_char and mytype.typecode in 'cu'): item = rffi.cast(lltype.Signed, item) return space.newint(item) if mytype.typecode in 'ILqQ': diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -892,14 +892,21 @@ assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" + def test_array_of_chars_equality(self): + input_bytes = '\x01\x63a\x00!' + a = self.array('c', input_bytes) + b = self.array('c', input_bytes) + b.byteswap() + assert a == b + def test_unicode_outofrange(self): input_unicode = u'\x01\u263a\x00\ufeff' a = self.array('u', input_unicode) b = self.array('u', input_unicode) b.byteswap() assert b[2] == u'\u0000' - raises(ValueError, "b[1]") # doesn't work - e = raises(ValueError, "a != b") # doesn't work + assert a != b + e = raises(ValueError, "b[0]") # doesn't work assert str(e.value) == ( "cannot operate on this array('u') because it contains" " character U+1000000 not in range [U+0000; U+10ffff]" diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py --- a/pypy/module/zlib/interp_zlib.py +++ b/pypy/module/zlib/interp_zlib.py @@ -344,8 +344,7 @@ raise oefmt(space.w_ValueError, "length must be greater than zero") if not self.stream: - raise zlib_error(space, - "compressor object already flushed") + return space.newbytes('') data = self.unconsumed_tail try: self.lock() diff --git a/pypy/module/zlib/test/test_zlib.py b/pypy/module/zlib/test/test_zlib.py --- a/pypy/module/zlib/test/test_zlib.py +++ b/pypy/module/zlib/test/test_zlib.py @@ -421,4 +421,5 @@ dco = zlib.decompressobj() dco.decompress(x) dco.flush() - raises(self.zlib.error, dco.flush) + # multiple flush calls should not raise + dco.flush() diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -728,6 +728,7 @@ raises(TypeError, 'hello'.translate) raises(ValueError, "\xff".translate, {0xff: sys.maxunicode+1}) + raises(TypeError, u'x'.translate, {ord('x'):0x110000}) def test_maketrans(self): assert 'abababc' == 'abababc'.translate({'b': ''}) From pypy.commits at gmail.com Tue Apr 23 03:45:22 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 23 Apr 2019 00:45:22 -0700 (PDT) Subject: [pypy-commit] buildbot default: disable py3.6 onlyIfChanged Message-ID: <5cbec292.1c69fb81.b027f.7817@mx.google.com> Author: Matti Picus Branch: Changeset: r1083:84d044d684af Date: 2019-04-23 10:44 +0300 http://bitbucket.org/pypy/buildbot/changeset/84d044d684af/ Log: disable py3.6 onlyIfChanged diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -350,7 +350,7 @@ JITMACOSX64, # on xerxes JITWIN32, # on SalsaSalsa ], branch="py3.6", hour=3, minute=0, - onlyIfChanged=True, + # onlyIfChanged=True, # doesn't work - no builds are triggered 2019-04-23 ), # this one has faithfully run every night even though the latest From pypy.commits at gmail.com Tue Apr 23 03:59:57 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 23 Apr 2019 00:59:57 -0700 (PDT) Subject: [pypy-commit] pypy default: remove arm32 builds, update for python3 Message-ID: <5cbec5fd.1c69fb81.b3a9e.fb59@mx.google.com> Author: Matti Picus Branch: Changeset: r96539:539ac859532e Date: 2019-04-23 10:59 +0300 http://bitbucket.org/pypy/pypy/changeset/539ac859532e/ Log: remove arm32 builds, update for python3 diff --git a/pypy/tool/release/force-builds.py b/pypy/tool/release/force-builds.py --- a/pypy/tool/release/force-builds.py +++ b/pypy/tool/release/force-builds.py @@ -8,8 +8,13 @@ modified by PyPy team """ +from __future__ import absolute_import, division, print_function -import os, sys, urllib, subprocess +import os, sys, subprocess +try: + from urllib2 import quote +except ImportError: + from urllib.request import quote from twisted.internet import reactor, defer from twisted.python import log @@ -29,10 +34,10 @@ 'pypy-c-jit-macosx-x86-64', 'pypy-c-jit-win-x86-32', 'pypy-c-jit-linux-s390x', - 'build-pypy-c-jit-linux-armhf-raspbian', - 'build-pypy-c-jit-linux-armel', +# 'build-pypy-c-jit-linux-armhf-raspbian', +# 'build-pypy-c-jit-linux-armel', 'rpython-linux-x86-32', - 'rpython-linux-x86-64' + 'rpython-linux-x86-64', 'rpython-win-x86-32' ] @@ -54,7 +59,7 @@ log.err(err, "Build force failure") for builder in BUILDERS: - print 'Forcing', builder, '...' + print('Forcing', builder, '...') url = "http://" + server + "/builders/" + builder + "/force" args = [ ('username', user), @@ -63,15 +68,15 @@ ('submit', 'Force Build'), ('branch', branch), ('comments', "Forced by command line script")] - url = url + '?' + '&'.join([k + '=' + urllib.quote(v) for (k, v) in args]) + url = url + '?' + '&'.join([k + '=' + quote(v) for (k, v) in args]) requests.append( - lock.run(client.getPage, url, followRedirect=False).addErrback(ebList)) + lock.run(client.getPage, url.encode('utf-8'), followRedirect=False).addErrback(ebList)) d = defer.gatherResults(requests) d.addErrback(log.err) d.addCallback(lambda ign: reactor.stop()) reactor.run() - print 'See http://buildbot.pypy.org/summary after a while' + print('See http://buildbot.pypy.org/summary after a while') if __name__ == '__main__': log.startLogging(sys.stdout) @@ -86,6 +91,6 @@ try: subprocess.check_call(['hg','id','-r', options.branch]) except subprocess.CalledProcessError: - print 'branch', options.branch, 'could not be found in local repository' + print('branch', options.branch, 'could not be found in local repository') sys.exit(-1) main(options.branch, options.server, user=options.user) From pypy.commits at gmail.com Tue Apr 23 09:00:42 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 23 Apr 2019 06:00:42 -0700 (PDT) Subject: [pypy-commit] pypy semlock-deadlock: add a test that hangs with SemLock (issue 2953) Message-ID: <5cbf0c7a.1c69fb81.94a4c.61be@mx.google.com> Author: Matti Picus Branch: semlock-deadlock Changeset: r96540:09ebb064a7b8 Date: 2019-04-23 15:33 +0300 http://bitbucket.org/pypy/pypy/changeset/09ebb064a7b8/ Log: add a test that hangs with SemLock (issue 2953) diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -108,3 +108,15 @@ with sem: assert sem._count() == 1 assert sem._count() == 0 + + def test_in_threads(self): + from _multiprocessing import SemLock + from threading import Thread + l = SemLock(0, 1, 1) + def f(): + for i in range(10000): + with l: + pass + threads = [Thread(None, f) for i in range(2)] + [t.start() for t in threads] + [t.join() for t in threads] From pypy.commits at gmail.com Tue Apr 23 09:00:44 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 23 Apr 2019 06:00:44 -0700 (PDT) Subject: [pypy-commit] pypy semlock-deadlock: add debugging code for test_in_threads Message-ID: <5cbf0c7c.1c69fb81.9887d.d00a@mx.google.com> Author: Matti Picus Branch: semlock-deadlock Changeset: r96541:9f2243789dfb Date: 2019-04-23 15:59 +0300 http://bitbucket.org/pypy/pypy/changeset/9f2243789dfb/ Log: add debugging code for test_in_threads diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -333,11 +333,15 @@ _sem_close_no_errno(handle) def semlock_acquire(self, space, block, w_timeout): + import threading + myid = threading.current_thread().ident if not block: + print 'not expected' deadline = lltype.nullptr(TIMESPECP.TO) elif space.is_none(w_timeout): deadline = lltype.nullptr(TIMESPECP.TO) else: + print 'not expected' timeout = space.float_w(w_timeout) sec = int(timeout) nsec = int(1e9 * (timeout - sec) + 0.5) @@ -356,12 +360,16 @@ while True: try: if not block: + print 'not expected' sem_trywait(self.handle) elif not deadline: + print 'sem_wait', myid sem_wait(self.handle) else: + print 'not expected' sem_timedwait(self.handle, deadline) except OSError as e: + print str(e) if e.errno == errno.EINTR: # again _check_signals(space) @@ -369,8 +377,9 @@ elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT): return False raise + print 4, myid _check_signals(space) - + print 5, myid return True finally: if deadline: @@ -378,6 +387,9 @@ def semlock_release(self, space): + import threading + myid = threading.current_thread().ident + print 'semlock_release', myid if self.kind == RECURSIVE_MUTEX: sem_post(self.handle) return From pypy.commits at gmail.com Fri Apr 26 08:16:05 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 26 Apr 2019 05:16:05 -0700 (PDT) Subject: [pypy-commit] cffi default: Fix C integer division. Add modulo. Message-ID: <5cc2f685.1c69fb81.45e12.8d46@mx.google.com> Author: Armin Rigo Branch: Changeset: r3273:1fc05b4f57de Date: 2019-04-26 14:15 +0200 http://bitbucket.org/cffi/cffi/changeset/1fc05b4f57de/ Log: Fix C integer division. Add modulo. diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -868,8 +868,9 @@ elif exprnode.op == '*': return left * right elif exprnode.op == '/': - # do integer division! - return left // right + return self._c_div(left, right) + elif exprnode.op == '%': + return left - self._c_div(left, right) * right elif exprnode.op == '<<': return left << right elif exprnode.op == '>>': @@ -884,6 +885,12 @@ raise FFIError(":%d: unsupported expression: expected a " "simple numeric constant" % exprnode.coord.line) + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + def _build_enum_type(self, explicit_name, decls): if decls is not None: partial = False diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -2534,3 +2534,29 @@ x.p = p x.cyclic = x del p, x + +def test_arithmetic_in_cdef(): + for a in [0, 11, 15]: + ffi = FFI() + ffi.cdef(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + lib = ffi.verify(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + # the verify() crashes if the values in the enum are different from + # the values we computed ourselves from the cdef() From pypy.commits at gmail.com Fri Apr 26 08:16:01 2019 From: pypy.commits at gmail.com (codypiersall) Date: Fri, 26 Apr 2019 05:16:01 -0700 (PDT) Subject: [pypy-commit] cffi default: Add support for more binary ops in enum definitions. Message-ID: <5cc2f681.1c69fb81.95587.d453@mx.google.com> Author: Cody Piersall Branch: Changeset: r3271:acdaa0cb8906 Date: 2019-02-02 13:11 -0600 http://bitbucket.org/cffi/cffi/changeset/acdaa0cb8906/ Log: Add support for more binary ops in enum definitions. diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -850,15 +850,28 @@ "the actual array length in this context" % exprnode.coord.line) # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '+'): - return (self._parse_constant(exprnode.left) + - self._parse_constant(exprnode.right)) - # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '-'): - return (self._parse_constant(exprnode.left) - - self._parse_constant(exprnode.right)) + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + # do integer division! + return left // right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right # raise FFIError(":%d: unsupported expression: expected a " "simple numeric constant" % exprnode.coord.line) diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -409,7 +409,17 @@ def test_enum(): ffi = FFI() ffi.cdef(""" - enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1}; + enum Enum { + POS = +1, + TWO = 2, + NIL = 0, + NEG = -1, + ADDSUB = (POS+TWO)-1, + DIVMULINT = (3 * 3) / 2, + SHIFT = (1 << 3) >> 1, + BINOPS = (0x7 & 0x1) | 0x8, + XOR = 0xf ^ 0xa + }; """) needs_dlopen_none() C = ffi.dlopen(None) @@ -417,7 +427,11 @@ assert C.TWO == 2 assert C.NIL == 0 assert C.NEG == -1 - assert C.OP == 2 + assert C.ADDSUB == 2 + assert C.DIVMULINT == 4 + assert C.SHIFT == 4 + assert C.BINOPS == 0b1001 + assert C.XOR == 0b0101 def test_stdcall(): ffi = FFI() @@ -466,3 +480,4 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + From pypy.commits at gmail.com Fri Apr 26 08:16:04 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 26 Apr 2019 05:16:04 -0700 (PDT) Subject: [pypy-commit] cffi default: merge pull request #96. Thanks Cody! Message-ID: <5cc2f684.1c69fb81.3eca7.5aaa@mx.google.com> Author: Armin Rigo Branch: Changeset: r3272:4878938ac504 Date: 2019-04-26 13:59 +0200 http://bitbucket.org/cffi/cffi/changeset/4878938ac504/ Log: merge pull request #96. Thanks Cody! diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -858,15 +858,28 @@ "the actual array length in this context" % exprnode.coord.line) # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '+'): - return (self._parse_constant(exprnode.left) + - self._parse_constant(exprnode.right)) - # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '-'): - return (self._parse_constant(exprnode.left) - - self._parse_constant(exprnode.right)) + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + # do integer division! + return left // right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right # raise FFIError(":%d: unsupported expression: expected a " "simple numeric constant" % exprnode.coord.line) diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -409,7 +409,17 @@ def test_enum(): ffi = FFI() ffi.cdef(""" - enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1}; + enum Enum { + POS = +1, + TWO = 2, + NIL = 0, + NEG = -1, + ADDSUB = (POS+TWO)-1, + DIVMULINT = (3 * 3) / 2, + SHIFT = (1 << 3) >> 1, + BINOPS = (0x7 & 0x1) | 0x8, + XOR = 0xf ^ 0xa + }; """) needs_dlopen_none() C = ffi.dlopen(None) @@ -417,7 +427,11 @@ assert C.TWO == 2 assert C.NIL == 0 assert C.NEG == -1 - assert C.OP == 2 + assert C.ADDSUB == 2 + assert C.DIVMULINT == 4 + assert C.SHIFT == 4 + assert C.BINOPS == 0b1001 + assert C.XOR == 0b0101 def test_stdcall(): ffi = FFI() From pypy.commits at gmail.com Sat Apr 27 11:23:20 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 27 Apr 2019 08:23:20 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: Simplify MetaInterp.get_procedure_token() Message-ID: <5cc473e8.1c69fb81.16767.8319@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96543:39a8b2657437 Date: 2019-04-27 16:22 +0100 http://bitbucket.org/pypy/pypy/changeset/39a8b2657437/ Log: Simplify MetaInterp.get_procedure_token() diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1282,8 +1282,11 @@ if self.metainterp.seen_loop_header_for_jdindex < 0: if not any_operation: return - if self.metainterp.portal_call_depth or not self.metainterp.get_procedure_token(greenboxes, True): - if not jitdriver_sd.no_loop_header: + if not jitdriver_sd.no_loop_header: + if self.metainterp.portal_call_depth: + return + ptoken = self.metainterp.get_procedure_token(greenboxes) + if not has_compiled_targets(ptoken): return # automatically add a loop_header if there is none self.metainterp.seen_loop_header_for_jdindex = jdindex @@ -2562,9 +2565,12 @@ # that failed; # - if self.resumekey is a ResumeFromInterpDescr, it starts directly # from the interpreter. + num_green_args = self.jitdriver_sd.num_green_args if not self.partial_trace: # FIXME: Support a retrace to be a bridge as well as a loop - self.compile_trace(live_arg_boxes) + ptoken = self.get_procedure_token(greenboxes) + if has_compiled_targets(ptoken): + self.compile_trace(live_arg_boxes, ptoken) # raises in case it works -- which is the common case, hopefully, # at least for bridges starting from a guard. @@ -2573,7 +2579,6 @@ # green keys, representing the beginning of the same loop as the one # we end now. - num_green_args = self.jitdriver_sd.num_green_args for j in range(len(self.current_merge_points)-1, -1, -1): original_boxes, start = self.current_merge_points[j] assert len(original_boxes) == len(live_arg_boxes) @@ -2720,25 +2725,19 @@ self.history.set_inputargs(inputargs, self.staticdata) assert not exception - def get_procedure_token(self, greenkey, with_compiled_targets=False): + def get_procedure_token(self, greenkey): JitCell = self.jitdriver_sd.warmstate.JitCell cell = JitCell.get_jit_cell_at_key(greenkey) if cell is None: return None - token = cell.get_procedure_token() - if with_compiled_targets: - if not token: - return None - if not token.target_tokens: - return None - return token + return cell.get_procedure_token() def compile_loop(self, original_boxes, live_arg_boxes, start, try_disabling_unroll=False): num_green_args = self.jitdriver_sd.num_green_args greenkey = original_boxes[:num_green_args] ptoken = self.get_procedure_token(greenkey) - if ptoken is not None and ptoken.target_tokens is not None: + if has_compiled_targets(ptoken): # XXX this path not tested, but shown to occur on pypy-c :-( self.staticdata.log('cancelled: we already have a token now') raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) @@ -2767,24 +2766,19 @@ live_arg_boxes[num_green_args:], self.partial_trace, self.resumekey, self.exported_state) - def compile_trace(self, live_arg_boxes): + def compile_trace(self, live_arg_boxes, ptoken): num_green_args = self.jitdriver_sd.num_green_args - greenkey = live_arg_boxes[:num_green_args] - target_jitcell_token = self.get_procedure_token(greenkey, True) - if not target_jitcell_token: - return - cut_at = self.history.get_trace_position() self.potential_retrace_position = cut_at self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None, - descr=target_jitcell_token) + descr=ptoken) self.history.ends_with_jump = True self.history.trace.tracing_done() try: target_token = compile.compile_trace(self, self.resumekey, live_arg_boxes[num_green_args:]) finally: - self.history.cut(cut_at) # pop the jump + self.history.cut(cut_at) # pop the jump self.history.ends_with_jump = False self.raise_if_successful(live_arg_boxes, target_token) @@ -3451,3 +3445,6 @@ return False else: return True + +def has_compiled_targets(token): + return bool(token) and bool(token.target_tokens) From pypy.commits at gmail.com Sat Apr 27 11:25:00 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 27 Apr 2019 08:25:00 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: hg merge default Message-ID: <5cc4744c.1c69fb81.ece7d.12f4@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96544:5ae00718c328 Date: 2019-04-27 16:23 +0100 http://bitbucket.org/pypy/pypy/changeset/5ae00718c328/ Log: hg merge default diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -10,10 +10,6 @@ 32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1 10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0 9c4588d731b7fe0b08669bd732c2b676cb0a8233 release-2.5.1 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0 f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0 @@ -24,17 +20,10 @@ b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2 40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 -40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 d7724c0a5700b895a47de44074cdf5fd659a988f RevDB-pypy2.7-v5.4.1 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0 e90317857d27917bf840caf675832292ee070510 RevDB-pypy2.7-v5.6.1 @@ -45,33 +34,20 @@ 2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1 c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0 a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0 0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0 3f6eaa010fce78cc7973bdc1dfdb95970f08fed2 release-pypy3.5-v5.10.1 ab0b9caf307db6592905a80b8faffd69b39005b8 release-pypy2.7-v6.0.0 fdd60ed87e941677e8ea11acf9f1819466521bf2 release-pypy3.5-v6.0.0 9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 -9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 c8805ee6d7846ca2722b106eeaa2f128c699aba3 release-pypy2.7-v7.0.0 -1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 -bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 -bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0 -6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 -6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0 -7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 -7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0 de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 +784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1 +8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1 + diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -110,6 +110,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -125,7 +126,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -254,6 +254,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -403,6 +404,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -290,7 +290,11 @@ else: bo = byteorder[sys.byteorder] flds = [] + cum_size = 0 for name, obj in typ._fields_: + padding = typ._ffistruct_.fieldoffset(name) - cum_size + if padding: + flds.append('%dx' % padding) # Trim off the leading '<' or '>' ch = get_format_str(obj)[1:] if (ch) == 'B': @@ -301,6 +305,7 @@ flds.append(':') flds.append(name) flds.append(':') + cum_size += typ._ffistruct_.fieldsize(name) return 'T{' + ''.join(flds) + '}' elif hasattr(typ, '_type_'): ch = typ._type_ diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.12.2 +Version: 1.12.3 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.2" -__version_info__ = (1, 12, 2) +__version__ = "1.12.3" +__version_info__ = (1, 12, 3) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -223,7 +223,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.2" + "\ncompiled with cffi version: 1.12.3" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -77,6 +77,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -92,7 +93,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -221,6 +221,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -370,6 +371,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -88,7 +88,9 @@ There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times -if the object is resurrected and dies again. The ``__del__`` methods are +if the object is resurrected and dies again (at least it is reliably so in +older CPythons; newer CPythons try to call destructors not more than once, +but there are counter-examples). The ``__del__`` methods are called in "the right" order if they are on objects pointing to each other, as in CPython, but unlike CPython, if there is a dead cycle of objects referencing each other, their ``__del__`` methods are called anyway; diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-v7.1.1.rst release-v7.1.0.rst release-v7.0.0.rst release-v6.0.0.rst diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-pypy2-7.1.0.rst whatsnew-pypy2-7.0.0.rst whatsnew-pypy2-6.0.0.rst whatsnew-pypy2-5.10.0.rst diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v7.1.1.rst @@ -0,0 +1,105 @@ +========================================= +PyPy v7.1.1: release of 2.7, and 3.6-beta +========================================= + +The PyPy team is proud to release a bug-fix release version 7.1.1 of PyPy, which +includes two different interpreters: + + - PyPy2.7, which is an interpreter supporting the syntax and the features of + Python 2.7 + + - PyPy3.6-beta: this is the second official release of PyPy to support 3.6 + features, although it is still considered beta quality. + +The interpreters are based on much the same codebase, thus the double +release. + +As always, this release is 100% compatible with the previous one and fixed +several issues and bugs raised by the growing community of PyPy users. +We strongly recommend updating. + +The PyPy3.6 release is still not production quality so your mileage may vary. +There are open issues with incomplete compatibility and c-extension support. + +You can download the v7.1.1 releases here: + + http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project. If PyPy is not quite good enough for your needs, we are available for +direct consulting work. + +We would also like to thank our contributors and encourage new people to join +the project. PyPy has many layers and we need help with all of them: `PyPy`_ +and `RPython`_ documentation improvements, tweaking popular modules to run +on pypy, or general `help`_ with making RPython's JIT even better. + +.. _`PyPy`: index.html +.. _`RPython`: https://rpython.readthedocs.org +.. _`help`: project-ideas.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7, 3.6. It's fast (`PyPy and CPython 2.7.x`_ performance +comparison) due to its integrated tracing JIT compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +This PyPy release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +Unfortunately at the moment of writing our ARM buildbots are out of service, +so for now we are **not** releasing any binary for the ARM architecture, +although PyPy does support ARM 32 bit processors. + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + + +Changelog +========= + +Changes shared across versions: + +* Improve performance of ``u''.append`` + +* Prevent a crash in ``zlib`` when flushing a closed stream + +* Fix a few corner cases when encountering unicode values above 0x110000 + +* Teach the JIT how to handle very large constant lists, sets, or dicts +* Fix building on ARM32 (issue 2984_) +* Fix a bug in register assignment in ARM32 +* Package windows DLLs needed by cffi modules next to the cffi c-extensions + (issue 2988_) +* Cleanup and refactor JIT code to remove ``rpython.jit.metainterp.typesystem`` +* Fix memoryviews of ctype structures with padding, (cpython issue 32780_) +* CFFI updated to as-yet-unreleased 1.12.3 + +Python 3.6 only: + +* Override some ``errno.E*`` values that were added to MSVC in v2010 + so that ``errno.E* == errno.WSAE*`` as in CPython +* Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the + AST level) +* ``str.maketrans`` was broken (issue 2991_) +* Raise a ``TypeError`` when using buffers and unicode such as ``''.strip(buffer)`` + and ``'a' < buffer`` +* Support ``_overlapped`` and asyncio on win32 +* Fix an issue where ``''.join(list_of_strings)`` would rarely confuse utf8 and + bytes (issue 2997_) + +.. _2984: https://bitbucket.org/pypy/pypy/issues/2984 +.. _2991: https://bitbucket.org/pypy/pypy/issues/2991 +.. _2988: https://bitbucket.org/pypy/pypy/issues/2988 +.. _2997: https://bitbucket.org/pypy/pypy/issues/2997 +.. _32780: https://bugs.python.org/issue32780 diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -12,3 +12,7 @@ .. branch: jit-cleanup Remove rpython.jit.metainterp.typesystem and clean up related code in rpython/jit/ + +.. branch: datetime_api_27 + +Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi from rpython.rtyper.lltypesystem import rffi -VERSION = "1.12.2" +VERSION = "1.12.3" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -74,8 +74,8 @@ lgt = min(arr1.len, arr2.len) for i in range(lgt): arr_eq_driver.jit_merge_point(comp_func=comp_op) - w_elem1 = arr1.w_getitem(space, i) - w_elem2 = arr2.w_getitem(space, i) + w_elem1 = arr1.w_getitem(space, i, integer_instead_of_char=True) + w_elem2 = arr2.w_getitem(space, i, integer_instead_of_char=True) if comp_op == EQ: res = space.eq_w(w_elem1, w_elem2) if not res: @@ -1036,10 +1036,11 @@ else: self.fromsequence(w_iterable) - def w_getitem(self, space, idx): + def w_getitem(self, space, idx, integer_instead_of_char=False): item = self.get_buffer()[idx] keepalive_until_here(self) - if mytype.typecode in 'bBhHil': + if mytype.typecode in 'bBhHil' or ( + integer_instead_of_char and mytype.typecode in 'cu'): item = rffi.cast(lltype.Signed, item) return space.newint(item) if mytype.typecode in 'IL': @@ -1053,21 +1054,17 @@ code = r_uint(ord(item)) # cpython will allow values > sys.maxunicode # while silently truncating the top bits - if code <= r_uint(0x7F): - # Encode ASCII - item = chr(code) - elif code <= r_uint(0x07FF): - item = (chr((0xc0 | (code >> 6))) + - chr((0x80 | (code & 0x3f)))) - elif code <= r_uint(0xFFFF): - item = (chr((0xe0 | (code >> 12))) + - chr((0x80 | ((code >> 6) & 0x3f))) + - chr((0x80 | (code & 0x3f)))) - else: - item = (chr((0xf0 | (code >> 18)) & 0xff) + - chr((0x80 | ((code >> 12) & 0x3f))) + - chr((0x80 | ((code >> 6) & 0x3f))) + - chr((0x80 | (code & 0x3f)))) + # For now I (arigo) am going to ignore that and + # raise a ValueError always here, instead of getting + # some invalid utf8-encoded string which makes things + # potentially explode left and right. + try: + item = rutf8.unichr_as_utf8(code) + except rutf8.OutOfRange: + raise oefmt(space.w_ValueError, + "cannot operate on this array('u') because it contains" + " character %s not in range [U+0000; U+10ffff]" + " at index %d", 'U+%x' % code, idx) return space.newutf8(item, 1) assert 0, "unreachable" diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -846,12 +846,25 @@ assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" + def test_array_of_chars_equality(self): + input_bytes = '\x01\x63a\x00!' + a = self.array('c', input_bytes) + b = self.array('c', input_bytes) + b.byteswap() + assert a == b + def test_unicode_outofrange(self): input_unicode = u'\x01\u263a\x00\ufeff' a = self.array('u', input_unicode) b = self.array('u', input_unicode) b.byteswap() + assert b[2] == u'\u0000' assert a != b + e = raises(ValueError, "b[0]") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") assert str(a) == "array('u', %r)" % (input_unicode,) assert str(b) == ("array('u', )") diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -67,6 +67,14 @@ _PyDelta_FromDelta.api_func.functype, _PyDelta_FromDelta.api_func.get_wrapper(space)) + datetimeAPI.c_DateTime_FromTimestamp = llhelper( + _PyDateTime_FromTimestamp.api_func.functype, + _PyDateTime_FromTimestamp.api_func.get_wrapper(space)) + + datetimeAPI.c_Date_FromTimestamp = llhelper( + _PyDate_FromTimestamp.api_func.functype, + _PyDate_FromTimestamp.api_func.get_wrapper(space)) + state.datetimeAPI.append(datetimeAPI) return state.datetimeAPI[0] @@ -243,8 +251,16 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("datetime")) + return _PyDateTime_FromTimestamp(space, w_type, w_args, None) + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def _PyDateTime_FromTimestamp(space, w_type, w_args, w_kwds): + """Implementation of datetime.fromtimestamp that matches the signature for + PyDateTimeCAPI.DateTime_FromTimestamp + """ w_method = space.getattr(w_type, space.newtext("fromtimestamp")) - return space.call(w_method, w_args) + + return space.call(w_method, w_args, w_kwds=w_kwds) @cpython_api([PyObject], PyObject) def PyDate_FromTimestamp(space, w_args): @@ -253,6 +269,12 @@ """ w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("date")) + return _PyDate_FromTimestamp(space, w_type, w_args) + + at cpython_api([PyObject, PyObject], PyObject) +def _PyDate_FromTimestamp(space, w_type, w_args): + """Implementation of date.fromtimestamp that matches the signature for + PyDateTimeCAPI.Date_FromTimestamp""" w_method = space.getattr(w_type, space.newtext("fromtimestamp")) return space.call(w_method, w_args) diff --git a/pypy/module/cpyext/parse/cpyext_datetime.h b/pypy/module/cpyext/parse/cpyext_datetime.h --- a/pypy/module/cpyext/parse/cpyext_datetime.h +++ b/pypy/module/cpyext/parse/cpyext_datetime.h @@ -13,6 +13,10 @@ PyObject*, PyTypeObject*); PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); } PyDateTime_CAPI; typedef struct diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -146,6 +146,41 @@ 2000, 6, 6, 6, 6, 6, 6, Py_None, PyDateTimeAPI->DateTimeType); """), + ("new_datetime_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(2, ts, Py_None); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL); + Py_DECREF(tsargs); + return rv; + """), + ("new_dt_fromts_tzinfo", "METH_O", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(200000.0); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *tskwargs = PyDict_New(); + + Py_INCREF(args); + PyDict_SetItemString(tskwargs, "tz", args); + PyObject *rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, tskwargs); + Py_DECREF(tsargs); + Py_DECREF(tskwargs); + return rv; + """), + ("new_date_fromtimestamp", "METH_NOARGS", + """ PyDateTime_IMPORT; + PyObject *ts = PyFloat_FromDouble(1430366400.0); + Py_INCREF(Py_None); + PyObject *tsargs = PyTuple_Pack(1, ts); + PyObject *rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs); + Py_DECREF(tsargs); + return rv; + """), + ], prologue='#include "datetime.h"\n') import datetime assert module.new_date() == datetime.date(2000, 6, 6) @@ -153,6 +188,28 @@ assert module.new_datetime() == datetime.datetime( 2000, 6, 6, 6, 6, 6, 6) + class UTC(datetime.tzinfo): + def utcoffset(self, dt): + return datetime.timedelta(hours=0) + + def dst(self, dt): + return datetime.timedelta(0) + + def tzname(self, dt): + return "UTC" + + utc = UTC() + + # .fromtimestamp tests + assert (module.new_datetime_fromtimestamp() == + datetime.datetime.fromtimestamp(200000.0)) + + assert (module.new_dt_fromts_tzinfo(utc) == + datetime.datetime.fromtimestamp(200000.0, tz=utc)) + + assert (module.new_date_fromtimestamp() == + datetime.date.fromtimestamp(1430366400.0)) + def test_macros(self): module = self.import_extension('foo', [ ("test_date_macros", "METH_NOARGS", @@ -305,16 +362,18 @@ """), ], prologue='#include "datetime.h"\n') from datetime import tzinfo, datetime, timedelta, time + # copied from datetime documentation class GMT1(tzinfo): def __del__(self): - print 'deleting GMT1' + print('deleting GMT1') def utcoffset(self, dt): return timedelta(hours=1) + self.dst(dt) def dst(self, dt): return timedelta(0) def tzname(self,dt): return "GMT +1" + gmt1 = GMT1() dt1 = module.time_with_tzinfo(gmt1) assert dt1 == time(6, 6, 6, 6, gmt1) diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -43,9 +43,9 @@ guard_no_exception(descr=...) i100 = int_lt(i98, 0) guard_true(i100, descr=...) - i102 = call_i(ConstClass(_ll_4_str_eq_slice_char__rpy_stringPtr_Signed_Signed_Char), p55, i83, 1, i89, descr=) + i102 = call_i(ConstClass(_ll_4_str_eq_slice_char__rpy_stringPtr_Signed_Signed_Char), p13, i83, 1, i89, descr=) guard_true(i102, descr=...) - i104 = int_add(i74, 1) + i104 = int_add(i6, 1) --TICK-- jump(..., descr=...) """ % (-sys.maxint-1,)) diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py --- a/pypy/module/zlib/interp_zlib.py +++ b/pypy/module/zlib/interp_zlib.py @@ -352,8 +352,7 @@ raise oefmt(space.w_ValueError, "length must be greater than zero") if not self.stream: - raise zlib_error(space, - "compressor object already flushed") + return space.newbytes('') data = self.unconsumed_tail try: self.lock() diff --git a/pypy/module/zlib/test/test_zlib.py b/pypy/module/zlib/test/test_zlib.py --- a/pypy/module/zlib/test/test_zlib.py +++ b/pypy/module/zlib/test/test_zlib.py @@ -363,4 +363,5 @@ dco = zlib.decompressobj() dco.decompress(x) dco.flush() - raises(self.zlib.error, dco.flush) + # multiple flush calls should not raise + dco.flush() diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -711,6 +711,7 @@ raises(TypeError, u'hello'.translate) raises(TypeError, u'abababc'.translate, {ord('a'):''}) + raises(TypeError, u'x'.translate, {ord('x'):0x110000}) def test_unicode_from_encoded_object(self): assert unicode('x', 'utf-8') == u'x' @@ -1278,4 +1279,4 @@ assert str(e.value) == 'decoding Unicode is not supported' def test_newlist_utf8_non_ascii(self): - 'ä'.split("\n")[0] # does not crash \ No newline at end of file + 'ä'.split("\n")[0] # does not crash diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -42,13 +42,10 @@ self._length = length self._index_storage = rutf8.null_storage() if not we_are_translated(): - try: - # best effort, too expensive to handle surrogates - ulength = rutf8.codepoints_in_utf(utf8str) - except: - ulength = length - assert ulength == length - + # utf8str must always be a valid utf8 string, except maybe with + # explicit surrogate characters---which .decode('utf-8') doesn't + # special-case in Python 2, which is exactly what we want here + assert length == len(utf8str.decode('utf-8')) @staticmethod @@ -385,7 +382,7 @@ "or unicode") try: builder.append_code(codepoint) - except ValueError: + except rutf8.OutOfRange: raise oefmt(space.w_TypeError, "character mapping must be in range(0x110000)") return self.from_utf8builder(builder) diff --git a/pypy/tool/release/force-builds.py b/pypy/tool/release/force-builds.py --- a/pypy/tool/release/force-builds.py +++ b/pypy/tool/release/force-builds.py @@ -8,8 +8,13 @@ modified by PyPy team """ +from __future__ import absolute_import, division, print_function -import os, sys, urllib, subprocess +import os, sys, subprocess +try: + from urllib2 import quote +except ImportError: + from urllib.request import quote from twisted.internet import reactor, defer from twisted.python import log @@ -29,10 +34,10 @@ 'pypy-c-jit-macosx-x86-64', 'pypy-c-jit-win-x86-32', 'pypy-c-jit-linux-s390x', - 'build-pypy-c-jit-linux-armhf-raspbian', - 'build-pypy-c-jit-linux-armel', +# 'build-pypy-c-jit-linux-armhf-raspbian', +# 'build-pypy-c-jit-linux-armel', 'rpython-linux-x86-32', - 'rpython-linux-x86-64' + 'rpython-linux-x86-64', 'rpython-win-x86-32' ] @@ -54,7 +59,7 @@ log.err(err, "Build force failure") for builder in BUILDERS: - print 'Forcing', builder, '...' + print('Forcing', builder, '...') url = "http://" + server + "/builders/" + builder + "/force" args = [ ('username', user), @@ -63,15 +68,15 @@ ('submit', 'Force Build'), ('branch', branch), ('comments', "Forced by command line script")] - url = url + '?' + '&'.join([k + '=' + urllib.quote(v) for (k, v) in args]) + url = url + '?' + '&'.join([k + '=' + quote(v) for (k, v) in args]) requests.append( - lock.run(client.getPage, url, followRedirect=False).addErrback(ebList)) + lock.run(client.getPage, url.encode('utf-8'), followRedirect=False).addErrback(ebList)) d = defer.gatherResults(requests) d.addErrback(log.err) d.addCallback(lambda ign: reactor.stop()) reactor.run() - print 'See http://buildbot.pypy.org/summary after a while' + print('See http://buildbot.pypy.org/summary after a while') if __name__ == '__main__': log.startLogging(sys.stdout) @@ -86,6 +91,6 @@ try: subprocess.check_call(['hg','id','-r', options.branch]) except subprocess.CalledProcessError: - print 'branch', options.branch, 'could not be found in local repository' + print('branch', options.branch, 'could not be found in local repository') sys.exit(-1) main(options.branch, options.server, user=options.user) diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -109,9 +109,6 @@ wchar_t const* file, unsigned int line, uintptr_t pReserved) { - wprintf(L"Invalid parameter detected in function %s." - L" File: %s Line: %d\\n", function, file, line); - wprintf(L"Expression: %s\\n", expression); } RPY_EXTERN void* enter_suppress_iph(void) @@ -1265,16 +1262,16 @@ @replace_os_function('rename') @specialize.argtype(0, 1) def rename(path1, path2): - if not _WIN32: - handle_posix_error('rename', - c_rename(_as_bytes0(path1), _as_bytes0(path2))) - else: + if _WIN32: traits = _preferred_traits2(path1, path2) win32traits = make_win32_traits(traits) path1 = traits.as_str0(path1) path2 = traits.as_str0(path2) if not win32traits.MoveFileEx(path1, path2, 0): raise rwin32.lastSavedWindowsError() + else: + handle_posix_error('rename', + c_rename(_as_bytes0(path1), _as_bytes0(path2))) @specialize.argtype(0, 1) def replace(path1, path2): From pypy.commits at gmail.com Sat Apr 27 13:21:39 2019 From: pypy.commits at gmail.com (mattip) Date: Sat, 27 Apr 2019 10:21:39 -0700 (PDT) Subject: [pypy-commit] pypy semlock-deadlock: fix RECURSIVE semaphore by setting state before, not after, glibc call Message-ID: <5cc48fa3.1c69fb81.d5a9e.549a@mx.google.com> Author: Matti Picus Branch: semlock-deadlock Changeset: r96545:f3621100820d Date: 2019-04-27 09:18 -0700 http://bitbucket.org/pypy/pypy/changeset/f3621100820d/ Log: fix RECURSIVE semaphore by setting state before, not after, glibc call diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -46,7 +46,8 @@ eci = ExternalCompilationInfo( includes = ['sys/time.h', 'limits.h', - 'semaphore.h'], + 'semaphore.h', + ], libraries = libraries, ) @@ -333,15 +334,11 @@ _sem_close_no_errno(handle) def semlock_acquire(self, space, block, w_timeout): - import threading - myid = threading.current_thread().ident if not block: - print 'not expected' deadline = lltype.nullptr(TIMESPECP.TO) elif space.is_none(w_timeout): deadline = lltype.nullptr(TIMESPECP.TO) else: - print 'not expected' timeout = space.float_w(w_timeout) sec = int(timeout) nsec = int(1e9 * (timeout - sec) + 0.5) @@ -360,16 +357,12 @@ while True: try: if not block: - print 'not expected' sem_trywait(self.handle) elif not deadline: - print 'sem_wait', myid sem_wait(self.handle) else: - print 'not expected' sem_timedwait(self.handle, deadline) except OSError as e: - print str(e) if e.errno == errno.EINTR: # again _check_signals(space) @@ -377,9 +370,7 @@ elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT): return False raise - print 4, myid - _check_signals(space) - print 5, myid + _check_signals(space) return True finally: if deadline: @@ -387,9 +378,6 @@ def semlock_release(self, space): - import threading - myid = threading.current_thread().ident - print 'semlock_release', myid if self.kind == RECURSIVE_MUTEX: sem_post(self.handle) return @@ -451,6 +439,7 @@ self.count = 0 self.maxvalue = maxvalue self.register_finalizer(space) + self.last_tid = -1 def kind_get(self, space): return space.newint(self.kind) @@ -488,35 +477,42 @@ if self.kind == RECURSIVE_MUTEX and self._ismine(): self.count += 1 return space.w_True - + owner_id = self.last_tid try: + # Ideally these calls would be atomic. Since we cannot + # promise that, make sure we do not enable the fast-path + # through release anymore + self.last_tid = rthread.get_ident() got = semlock_acquire(self, space, block, w_timeout) except OSError as e: + self.last_tid = owner_id raise wrap_oserror(space, e) if got: - self.last_tid = rthread.get_ident() self.count += 1 return space.w_True else: + self.last_tid = owner_id return space.w_False def release(self, space): if self.kind == RECURSIVE_MUTEX: - if not self._ismine(): - raise oefmt(space.w_AssertionError, - "attempt to release recursive lock not owned by " - "thread") - if self.count > 1: + # another thread may be in the middle of an acquire and + # have set the last_tid already + if self._ismine() and self.count > 1: self.count -= 1 return try: + # Ideally these two calls would be atomic. Since we cannot + # promise that, make sure once we release the lock the count + # will be correct + self.count -= 1 semlock_release(self, space) except OSError as e: + self.count += 1 raise wrap_oserror(space, e) - self.count -= 1 def after_fork(self): self.count = 0 diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -112,11 +112,14 @@ def test_in_threads(self): from _multiprocessing import SemLock from threading import Thread + from time import sleep l = SemLock(0, 1, 1) - def f(): - for i in range(10000): + def f(id): + for i in range(1000): with l: pass - threads = [Thread(None, f) for i in range(2)] + threads = [Thread(None, f, args=(i,)) for i in range(2)] [t.start() for t in threads] + # if the RLock calls to sem_wait and sem_post do not match, + # one of the threads will block and the call to join will fail [t.join() for t in threads] From pypy.commits at gmail.com Sat Apr 27 11:23:18 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 27 Apr 2019 08:23:18 -0700 (PDT) Subject: [pypy-commit] pypy optimizeopt-cleanup: extract same_greenkey() helper and dedent some code Message-ID: <5cc473e6.1c69fb81.9136.ad86@mx.google.com> Author: Ronan Lamy Branch: optimizeopt-cleanup Changeset: r96542:add9a446f421 Date: 2019-04-23 23:47 +0100 http://bitbucket.org/pypy/pypy/changeset/add9a446f421/ Log: extract same_greenkey() helper and dedent some code diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2577,44 +2577,39 @@ for j in range(len(self.current_merge_points)-1, -1, -1): original_boxes, start = self.current_merge_points[j] assert len(original_boxes) == len(live_arg_boxes) - for i in range(num_green_args): - box1 = original_boxes[i] - box2 = live_arg_boxes[i] - assert isinstance(box1, Const) - if not box1.same_constant(box2): - break + if not same_greenkey(original_boxes, live_arg_boxes, num_green_args): + continue + if self.partial_trace: + if start != self.retracing_from: + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) # For now + # Found! Compile it as a loop. + # raises in case it works -- which is the common case + self.history.trace.tracing_done() + if self.partial_trace: + target_token = self.compile_retrace( + original_boxes, live_arg_boxes, start) + self.raise_if_successful(live_arg_boxes, target_token) + # creation of the loop was cancelled! + self.cancel_count += 1 + if self.cancelled_too_many_times(): + self.staticdata.log('cancelled too many times!') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) else: - if self.partial_trace: - if start != self.retracing_from: - raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) # For now - # Found! Compile it as a loop. - # raises in case it works -- which is the common case - self.history.trace.tracing_done() - if self.partial_trace: - target_token = self.compile_retrace( - original_boxes, live_arg_boxes, start) + target_token = self.compile_loop( + original_boxes, live_arg_boxes, start) + self.raise_if_successful(live_arg_boxes, target_token) + # creation of the loop was cancelled! + self.cancel_count += 1 + if self.cancelled_too_many_times(): + target_token = self.compile_loop( + original_boxes, live_arg_boxes, start, + try_disabling_unroll=True) self.raise_if_successful(live_arg_boxes, target_token) - # creation of the loop was cancelled! - self.cancel_count += 1 - if self.cancelled_too_many_times(): - self.staticdata.log('cancelled too many times!') - raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) - else: - target_token = self.compile_loop( - original_boxes, live_arg_boxes, start) - self.raise_if_successful(live_arg_boxes, target_token) - # creation of the loop was cancelled! - self.cancel_count += 1 - if self.cancelled_too_many_times(): - target_token = self.compile_loop( - original_boxes, live_arg_boxes, start, - try_disabling_unroll=True) - self.raise_if_successful(live_arg_boxes, target_token) - # - self.staticdata.log('cancelled too many times!') - raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) - self.exported_state = None - self.staticdata.log('cancelled, tracing more...') + # + self.staticdata.log('cancelled too many times!') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) + self.exported_state = None + self.staticdata.log('cancelled, tracing more...') # Otherwise, no loop found so far, so continue tracing. start = self.history.get_trace_position() @@ -3446,3 +3441,13 @@ frame._put_back_list_of_boxes(newvalue, 0, position) frame._put_back_list_of_boxes(newvalue, length1, position2) frame._put_back_list_of_boxes(newvalue, length1 + length2, position3) + +def same_greenkey(original_boxes, live_arg_boxes, num_green_args): + for i in range(num_green_args): + box1 = original_boxes[i] + box2 = live_arg_boxes[i] + assert isinstance(box1, Const) + if not box1.same_constant(box2): + return False + else: + return True From pypy.commits at gmail.com Sun Apr 28 11:51:34 2019 From: pypy.commits at gmail.com (mattip) Date: Sun, 28 Apr 2019 08:51:34 -0700 (PDT) Subject: [pypy-commit] pypy semlock-deadlock: revert f3621100820d in favor of moving state changes closer to sem_wait calls Message-ID: <5cc5cc06.1c69fb81.cb84c.ae94@mx.google.com> Author: Matti Picus Branch: semlock-deadlock Changeset: r96546:3f24275dc38b Date: 2019-04-28 08:50 -0700 http://bitbucket.org/pypy/pypy/changeset/3f24275dc38b/ Log: revert f3621100820d in favor of moving state changes closer to sem_wait calls diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -260,6 +260,8 @@ res = rwin32.WaitForSingleObject(self.handle, 0) if res != rwin32.WAIT_TIMEOUT: + self.last_tid = rthread.get_ident() + self.count += 1 return True msecs = full_msecs @@ -292,6 +294,8 @@ # handle result if res != rwin32.WAIT_TIMEOUT: + self.last_tid = rthread.get_ident() + self.count += 1 return True return False @@ -371,6 +375,8 @@ return False raise _check_signals(space) + self.last_tid = rthread.get_ident() + self.count += 1 return True finally: if deadline: @@ -477,40 +483,33 @@ if self.kind == RECURSIVE_MUTEX and self._ismine(): self.count += 1 return space.w_True - owner_id = self.last_tid try: - # Ideally these calls would be atomic. Since we cannot - # promise that, make sure we do not enable the fast-path - # through release anymore - self.last_tid = rthread.get_ident() + # sets self.last_tid and increments self.count + # those steps need to be as close as possible to + # acquiring the semlock for self._ismine() to support + # multiple threads got = semlock_acquire(self, space, block, w_timeout) except OSError as e: - self.last_tid = owner_id raise wrap_oserror(space, e) - if got: - self.count += 1 return space.w_True else: - self.last_tid = owner_id return space.w_False def release(self, space): if self.kind == RECURSIVE_MUTEX: - # another thread may be in the middle of an acquire and - # have set the last_tid already - if self._ismine() and self.count > 1: + if not self._ismine(): + raise oefmt(space.w_AssertionError, + "attempt to release recursive lock not owned by " + "thread") + if self.count > 1: self.count -= 1 return try: - # Ideally these two calls would be atomic. Since we cannot - # promise that, make sure once we release the lock the count - # will be correct + semlock_release(self, space) self.count -= 1 - semlock_release(self, space) except OSError as e: - self.count += 1 raise wrap_oserror(space, e) diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -17,6 +17,7 @@ def setup_class(cls): cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE) cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def test_semaphore(self): from _multiprocessing import SemLock @@ -114,10 +115,17 @@ from threading import Thread from time import sleep l = SemLock(0, 1, 1) - def f(id): - for i in range(1000): - with l: + if self.runappdirect: + def f(id): + for i in range(10000): pass + else: + def f(id): + for i in range(1000): + # reduce the probability of thread switching + # at exactly the wrong time in semlock_acquire + for j in range(10): + pass threads = [Thread(None, f, args=(i,)) for i in range(2)] [t.start() for t in threads] # if the RLock calls to sem_wait and sem_post do not match, From pypy.commits at gmail.com Mon Apr 29 02:16:56 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 28 Apr 2019 23:16:56 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Synchronize the three places listing flags (which were all three Message-ID: <5cc696d8.1c69fb81.4f692.fc61@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96547:267749f8253a Date: 2019-04-29 08:16 +0200 http://bitbucket.org/pypy/pypy/changeset/267749f8253a/ Log: Synchronize the three places listing flags (which were all three slightly out-of-sync, and out of sync with py3.6 too) diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -644,11 +644,13 @@ 'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type', - 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag', + 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_QuietFlag', + 'Py_InteractiveFlag', 'Py_InspectFlag', 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag', - 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag', - 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', - '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext', + 'Py_FrozenFlag', 'Py_IgnoreEnvironmentFlag', + 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory', + 'Py_UnbufferedStdioFlag', 'Py_HashRandomizationFlag', 'Py_IsolatedFlag', + '_Py_PackageContext', 'PyOS_InputHook', 'PyMem_RawMalloc', 'PyMem_RawCalloc', 'PyMem_RawRealloc', 'PyMem_RawFree', @@ -664,6 +666,8 @@ 'PyObject_Init', 'PyObject_InitVar', 'PyTuple_New', '_Py_Dealloc', ] +if sys.platform == "win32": + SYMBOLS_C.append('Py_LegacyWindowsStdioFlag') TYPES = {} FORWARD_DECLS = [] INIT_FUNCTIONS = [] diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -9,6 +9,7 @@ PyAPI_FUNC(void) Py_FatalError(const char *msg); /* taken from Python-3.2.3/Include/pydebug.h */ +/* Note: they are always 0 for now, expect Py_DebugFlag which is always 1 */ PyAPI_DATA(int) Py_DebugFlag; PyAPI_DATA(int) Py_VerboseFlag; PyAPI_DATA(int) Py_QuietFlag; @@ -20,11 +21,17 @@ PyAPI_DATA(int) Py_UseClassExceptionsFlag; PyAPI_DATA(int) Py_FrozenFlag; PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; -PyAPI_DATA(int) Py_DivisionWarningFlag; PyAPI_DATA(int) Py_DontWriteBytecodeFlag; PyAPI_DATA(int) Py_NoUserSiteDirectory; PyAPI_DATA(int) Py_UnbufferedStdioFlag; PyAPI_DATA(int) Py_HashRandomizationFlag; +PyAPI_DATA(int) Py_IsolatedFlag; + +#ifdef MS_WINDOWS +PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; +#endif + +#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) typedef struct { diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c --- a/pypy/module/cpyext/src/missing.c +++ b/pypy/module/cpyext/src/missing.c @@ -10,6 +10,7 @@ int Py_DebugFlag = 1; int Py_VerboseFlag = 0; +int Py_QuietFlag = 0; int Py_InteractiveFlag = 0; int Py_InspectFlag = 0; int Py_OptimizeFlag = 0; @@ -17,15 +18,17 @@ int Py_BytesWarningFlag = 0; int Py_UseClassExceptionsFlag = 0; int Py_FrozenFlag = 0; -int Py_TabcheckFlag = 0; -int Py_UnicodeFlag = 0; int Py_IgnoreEnvironmentFlag = 0; -int Py_DivisionWarningFlag = 0; int Py_DontWriteBytecodeFlag = 0; int Py_NoUserSiteDirectory = 0; -int _Py_QnewFlag = 0; -int Py_Py3kWarningFlag = 0; +int Py_UnbufferedStdioFlag = 0; int Py_HashRandomizationFlag = 0; +int Py_IsolatedFlag = 0; + +#ifdef MS_WINDOWS +int Py_LegacyWindowsStdioFlag = 0; +#endif + const char *Py_FileSystemDefaultEncoding; /* filled when cpyext is imported */ void _Py_setfilesystemdefaultencoding(const char *enc) { From pypy.commits at gmail.com Mon Apr 29 03:43:42 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 00:43:42 -0700 (PDT) Subject: [pypy-commit] pypy default: Try to fix this test, failing on 32-bit since the utf-8 merge Message-ID: <5cc6ab2e.1c69fb81.cbb4.6783@mx.google.com> Author: Armin Rigo Branch: Changeset: r96548:a4ec9f051cba Date: 2019-04-29 09:43 +0200 http://bitbucket.org/pypy/pypy/changeset/a4ec9f051cba/ Log: Try to fix this test, failing on 32-bit since the utf-8 merge diff --git a/lib-python/2.7/test/test_unicode.py b/lib-python/2.7/test/test_unicode.py --- a/lib-python/2.7/test/test_unicode.py +++ b/lib-python/2.7/test/test_unicode.py @@ -1652,10 +1652,10 @@ # when a string allocation fails with a MemoryError. # This used to crash the interpreter, # or leak references when the number was smaller. - charwidth = 4 if sys.maxunicode >= 0x10000 else 2 + charwidth = 2 # pypy: the char \u0123 is stored in two utf-8 bytes # Note: sys.maxsize is half of the actual max allocation because of # the signedness of Py_ssize_t. - alloc = lambda: u"a" * (sys.maxsize // charwidth * 2) + alloc = lambda: u"\u0123" * (sys.maxsize // charwidth * 2) self.assertRaises(MemoryError, alloc) self.assertRaises(MemoryError, alloc) From pypy.commits at gmail.com Mon Apr 29 03:54:54 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 00:54:54 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <5cc6adce.1c69fb81.9c974.f439@mx.google.com> Author: Armin Rigo Branch: Changeset: r96549:436c5f4660ab Date: 2019-04-29 09:54 +0200 http://bitbucket.org/pypy/pypy/changeset/436c5f4660ab/ Log: Test and fix diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -570,7 +570,7 @@ if not 0 <= x <= 0x10FFFF: raise oefmt(space.w_TypeError, "character mapping must be in range(0x110000)") - return rutf8.unichr_as_utf8(x) + return rutf8.unichr_as_utf8(x, allow_surrogates=True) elif space.is_w(w_ch, space.w_None): # Charmap may return None return errorchar diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -119,6 +119,7 @@ assert (charmap_decode("\x00\x01\x02", "strict", {0: u'\U0010FFFF', 1: u'b', 2: u'c'}) == (u"\U0010FFFFbc", 3)) + assert charmap_decode('\xff', "strict", {0xff: 0xd800}) == (u'\ud800', 1) def test_escape_decode(self): from _codecs import unicode_escape_decode as decode From pypy.commits at gmail.com Mon Apr 29 03:56:36 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 00:56:36 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <5cc6ae34.1c69fb81.69e60.eb57@mx.google.com> Author: Armin Rigo Branch: Changeset: r96550:d8a9df1bc3eb Date: 2019-04-29 09:55 +0200 http://bitbucket.org/pypy/pypy/changeset/d8a9df1bc3eb/ Log: Test and fix diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -1059,7 +1059,7 @@ # some invalid utf8-encoded string which makes things # potentially explode left and right. try: - item = rutf8.unichr_as_utf8(code) + item = rutf8.unichr_as_utf8(code, allow_surrogates=True) except rutf8.OutOfRange: raise oefmt(space.w_ValueError, "cannot operate on this array('u') because it contains" diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -871,6 +871,10 @@ assert a.tounicode() == input_unicode raises(ValueError, b.tounicode) # doesn't work + def test_unicode_surrogate(self): + a = self.array('u', u'\ud800') + assert a[0] == u'\ud800' + def test_weakref(self): import weakref a = self.array('c', 'Hi!') From pypy.commits at gmail.com Mon Apr 29 04:08:27 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 01:08:27 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <5cc6b0fb.1c69fb81.c848d.06ea@mx.google.com> Author: Armin Rigo Branch: Changeset: r96551:0fd3a83a1891 Date: 2019-04-29 10:07 +0200 http://bitbucket.org/pypy/pypy/changeset/0fd3a83a1891/ Log: Test and fix diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py --- a/pypy/module/_pypyjson/interp_decoder.py +++ b/pypy/module/_pypyjson/interp_decoder.py @@ -365,9 +365,11 @@ hexdigits = self.getslice(start, i) try: val = int(hexdigits, 16) - if sys.maxunicode > 65535 and 0xd800 <= val <= 0xdfff: + if sys.maxunicode > 65535 and 0xd800 <= val <= 0xdbff: # surrogate pair - if self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u': + if (self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u' and + self.ll_chars[i+2] in 'dD' and + self.ll_chars[i+3] in 'cdefCDEF'): val = self.decode_surrogate_pair(i, val) i += 6 except ValueError: diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -199,6 +199,17 @@ res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected + def test_unicode_not_a_surrogate_pair(self): + import _pypyjson + res = _pypyjson.loads('"z\\ud800\\ud800x"') + assert list(res) == [u'z', u'\ud800', u'\ud800', u'x'] + res = _pypyjson.loads('"z\\udbff\\uffffx"') + assert list(res) == [u'z', u'\udbff', u'\uffff', u'x'] + res = _pypyjson.loads('"z\\ud800\\ud834\\udd20x"') + assert res == u'z\ud800\U0001d120x' + res = _pypyjson.loads('"z\\udc00\\udc00x"') + assert list(res) == [u'z', u'\udc00', u'\udc00', u'x'] + def test_surrogate_pair(self): import _pypyjson json = '{"a":"\\uD83D"}' From pypy.commits at gmail.com Mon Apr 29 04:14:44 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 01:14:44 -0700 (PDT) Subject: [pypy-commit] pypy default: Consolidate code, avoids obscure checking of individual characters to know if Message-ID: <5cc6b274.1c69fb81.df112.1602@mx.google.com> Author: Armin Rigo Branch: Changeset: r96552:6efbf166cc90 Date: 2019-04-29 10:14 +0200 http://bitbucket.org/pypy/pypy/changeset/6efbf166cc90/ Log: Consolidate code, avoids obscure checking of individual characters to know if the numeric value will be in range diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py --- a/pypy/module/_pypyjson/interp_decoder.py +++ b/pypy/module/_pypyjson/interp_decoder.py @@ -365,12 +365,14 @@ hexdigits = self.getslice(start, i) try: val = int(hexdigits, 16) - if sys.maxunicode > 65535 and 0xd800 <= val <= 0xdbff: - # surrogate pair - if (self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u' and - self.ll_chars[i+2] in 'dD' and - self.ll_chars[i+3] in 'cdefCDEF'): - val = self.decode_surrogate_pair(i, val) + if (0xd800 <= val <= 0xdbff and + self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u'): + hexdigits = self.getslice(i+2, i+6) + lowsurr = int(hexdigits, 16) + if 0xdc00 <= lowsurr <= 0xdfff: + # decode surrogate pair + val = 0x10000 + (((val - 0xd800) << 10) | + (lowsurr - 0xdc00)) i += 6 except ValueError: self._raise("Invalid \uXXXX escape (char %d)", i-1) @@ -381,15 +383,6 @@ builder.append(utf8_ch) return i - def decode_surrogate_pair(self, i, highsurr): - """ uppon enter the following must hold: - chars[i] == "\\" and chars[i+1] == "u" - """ - i += 2 - hexdigits = self.getslice(i, i+4) - lowsurr = int(hexdigits, 16) # the possible ValueError is caugth by the caller - return 0x10000 + (((highsurr - 0xd800) << 10) | (lowsurr - 0xdc00)) - def decode_key(self, i): """ returns a wrapped unicode """ from rpython.rlib.rarithmetic import intmask From pypy.commits at gmail.com Mon Apr 29 04:24:28 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 01:24:28 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <5cc6b4bc.1c69fb81.874b6.f2ca@mx.google.com> Author: Armin Rigo Branch: Changeset: r96553:d1159d6fe0e6 Date: 2019-04-29 10:22 +0200 http://bitbucket.org/pypy/pypy/changeset/d1159d6fe0e6/ Log: Test and fix diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -450,8 +450,13 @@ elif c == 'c': return space.newbytes(func(add_arg, argdesc, ll_type)) elif c == 'u': - return space.newutf8(rutf8.unichr_as_utf8( - ord(func(add_arg, argdesc, ll_type))), 1) + code = ord(func(add_arg, argdesc, ll_type)) + try: + return space.newutf8(rutf8.unichr_as_utf8( + code, allow_surrogates=True), 1) + except rutf8.OutOfRange: + raise oefmt(space.w_ValueError, + "unicode character %d out of range", code) elif c == 'f' or c == 'd' or c == 'g': return space.newfloat(float(func(add_arg, argdesc, ll_type))) else: diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -347,6 +347,21 @@ arg2.free() a.free() + def test_unicode_array(self): + import _rawffi + A = _rawffi.Array('u') + a = A(6, u'\u1234') + assert a[0] == u'\u1234' + a[0] = u'\U00012345' + assert a[0] == u'\U00012345' + a[0] = u'\ud800' + assert a[0] == u'\ud800' + B = _rawffi.Array('i') + b = B.fromaddress(a.itemaddress(0), 1) + b[0] = 0xffffffff + raises(ValueError, "a[0]") + a.free() + def test_returning_unicode(self): import _rawffi A = _rawffi.Array('u') From pypy.commits at gmail.com Mon Apr 29 04:29:06 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 01:29:06 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <5cc6b5d2.1c69fb81.488c4.fb05@mx.google.com> Author: Armin Rigo Branch: Changeset: r96554:05fb831f48eb Date: 2019-04-29 10:26 +0200 http://bitbucket.org/pypy/pypy/changeset/05fb831f48eb/ Log: Test and fix diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -332,7 +332,8 @@ space = self.space if do_unicode: cp = rutf8.codepoint_at_pos(self.fmt, self.fmtpos - 1) - w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp)), 1) + w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp), + allow_surrogates=True), 1) else: cp = ord(self.fmt[self.fmtpos - 1]) w_s = space.newbytes(chr(cp)) diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py --- a/pypy/objspace/std/test/test_stringformat.py +++ b/pypy/objspace/std/test/test_stringformat.py @@ -218,6 +218,7 @@ def test_format_wrong_char(self): raises(ValueError, 'a%Zb'.__mod__, ((23,),)) + raises(ValueError, u'a%\ud800b'.__mod__, ((23,),)) def test_incomplete_format(self): raises(ValueError, '%'.__mod__, ((23,),)) From pypy.commits at gmail.com Mon Apr 29 04:29:07 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 01:29:07 -0700 (PDT) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <5cc6b5d3.1c69fb81.b5483.c296@mx.google.com> Author: Armin Rigo Branch: Changeset: r96555:4cbb314b4683 Date: 2019-04-29 10:28 +0200 http://bitbucket.org/pypy/pypy/changeset/4cbb314b4683/ Log: Test and fix diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -473,7 +473,8 @@ n = space.int_w(w_value) if do_unicode: try: - c = rutf8.unichr_as_utf8(r_uint(n)) + c = rutf8.unichr_as_utf8(r_uint(n), + allow_surrogates=True) except rutf8.OutOfRange: raise oefmt(space.w_OverflowError, "unicode character code out of range") diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py --- a/pypy/objspace/std/test/test_stringformat.py +++ b/pypy/objspace/std/test/test_stringformat.py @@ -236,6 +236,8 @@ raises(TypeError, '%c'.__mod__, ("bla",)) raises(TypeError, '%c'.__mod__, ("",)) raises(TypeError, '%c'.__mod__, (['c'],)) + surrogate = 0xd800 + assert u'%c' % surrogate == u'\ud800' def test_broken_unicode(self): raises(UnicodeDecodeError, 'Názov: %s'.__mod__, u'Jerry') From pypy.commits at gmail.com Mon Apr 29 05:12:37 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:12:37 -0700 (PDT) Subject: [pypy-commit] pypy default: Whack whack whack Message-ID: <5cc6c005.1c69fb81.a52f6.313a@mx.google.com> Author: Armin Rigo Branch: Changeset: r96556:265eccc9831f Date: 2019-04-29 11:11 +0200 http://bitbucket.org/pypy/pypy/changeset/265eccc9831f/ Log: Whack whack whack diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -350,6 +350,9 @@ raise oefmt(space.w_TypeError, "%T.__format__ must return string or unicode, not %T", w_obj, w_res) + if (space.isinstance_w(w_format_spec, space.w_unicode) and + not space.isinstance_w(w_res, space.w_unicode)): + w_res = space.unicode_from_object(w_res) return w_res def pow(space, w_obj1, w_obj2, w_obj3): diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -349,9 +349,11 @@ if recursive: spec = self._build_string(spec_start, end, level) w_rendered = self.space.format(w_obj, self.wrap(spec)) - unwrapper = "utf8_w" if self.is_unicode else "bytes_w" - to_interp = getattr(self.space, unwrapper) - return to_interp(w_rendered) + if self.is_unicode: + w_rendered = self.space.unicode_from_object(w_rendered) + return self.space.utf8_w(w_rendered) + else: + return self.space.bytes_w(w_rendered) def formatter_parser(self): self.parser_list_w = [] @@ -779,6 +781,7 @@ return out.build() def _format_int_or_long(self, w_num, kind): + # note: 'self.is_unicode' cannot be True any more here space = self.space if self._precision != -1: raise oefmt(space.w_ValueError, @@ -903,6 +906,7 @@ return "".join(buf[i:]) def format_int_or_long(self, w_num, kind): + # note: 'self.is_unicode' cannot be True any more here space = self.space if self._parse_spec("d", ">"): if self.is_unicode: @@ -992,6 +996,7 @@ fill, to_remainder, False)) def format_float(self, w_float): + # note: 'self.is_unicode' cannot be True any more here space = self.space if self._parse_spec("\0", ">"): if self.is_unicode: @@ -1155,6 +1160,7 @@ def format_complex(self, w_complex): """return the string representation of a complex number""" + # note: 'self.is_unicode' cannot be True any more here space = self.space #parse format specification, set associated variables if self._parse_spec("\0", ">"): @@ -1178,9 +1184,5 @@ @specialize.arg(2) def run_formatter(space, w_format_spec, meth, *args): - if space.isinstance_w(w_format_spec, space.w_unicode): - formatter = unicode_formatter(space, space.utf8_w(w_format_spec)) - return getattr(formatter, meth)(*args) - else: - formatter = str_formatter(space, space.bytes_w(w_format_spec)) - return getattr(formatter, meth)(*args) + formatter = str_formatter(space, space.bytes_w(w_format_spec)) + return getattr(formatter, meth)(*args) diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -258,6 +258,7 @@ def test_simple(self): assert format(self.i(2)) == "2" assert isinstance(format(self.i(2), u""), unicode) + assert isinstance(self.i(2).__format__(u""), str) def test_invalid(self): raises(ValueError, format, self.i(8), "s") @@ -471,3 +472,15 @@ assert isinstance(first, unicode) for x, y in l: assert isinstance(y, unicode) + + def test_format_char(self): + import sys + assert '{0:c}'.format(42) == '*' + raises(OverflowError, '{0:c}'.format, 1234) + # the rest looks unexpected, but that's also what CPython does + raises(UnicodeDecodeError, u'{0:c}'.format, 255) + raises(OverflowError, u'{0:c}'.format, 1234) + raises(OverflowError, u'{0:c}'.format, -1) + + def test_format_unicode_nonutf8_bytestring(self): + raises(UnicodeDecodeError, u'{0}'.format, '\xff') From pypy.commits at gmail.com Mon Apr 29 05:17:47 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:17:47 -0700 (PDT) Subject: [pypy-commit] pypy default: Last fix for unichr_as_utf8, this one only shows up after translation on 32-bit Message-ID: <5cc6c13b.1c69fb81.c34a4.82e0@mx.google.com> Author: Armin Rigo Branch: Changeset: r96557:346bab011f27 Date: 2019-04-29 11:16 +0200 http://bitbucket.org/pypy/pypy/changeset/346bab011f27/ Log: Last fix for unichr_as_utf8, this one only shows up after translation on 32-bit diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1233,7 +1233,7 @@ s, pos, pos + 4) result.append(r) continue - elif ch >= 0x110000: + elif r_uint(ch) >= 0x110000: r, pos = errorhandler(errors, public_encoding_name, "codepoint not in range(0x110000)", s, pos, len(s)) From pypy.commits at gmail.com Mon Apr 29 05:20:14 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:20:14 -0700 (PDT) Subject: [pypy-commit] pypy default: Increased CPython compatibility... Message-ID: <5cc6c1ce.1c69fb81.0b61.1292@mx.google.com> Author: Armin Rigo Branch: Changeset: r96558:98af59ed5466 Date: 2019-04-29 11:19 +0200 http://bitbucket.org/pypy/pypy/changeset/98af59ed5466/ Log: Increased CPython compatibility... diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -1147,8 +1147,8 @@ def test_format_repeat(self): assert format(u"abc", u"z<5") == u"abczz" assert format(u"abc", u"\u2007<5") == u"abc\u2007\u2007" - #CPython2 raises UnicodeEncodeError - assert format(123, u"\u2007<5") == u"123\u2007\u2007" + # raises UnicodeEncodeError, like CPython does + raises(UnicodeEncodeError, format, 123, u"\u2007<5") def test_formatting_char(self): for num in range(0x80,0x100): From pypy.commits at gmail.com Mon Apr 29 05:31:53 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:31:53 -0700 (PDT) Subject: [pypy-commit] pypy default: Back-port the test renaming Message-ID: <5cc6c489.1c69fb81.5bad4.5a90@mx.google.com> Author: Armin Rigo Branch: Changeset: r96559:698a28e5201e Date: 2019-04-29 11:31 +0200 http://bitbucket.org/pypy/pypy/changeset/698a28e5201e/ Log: Back-port the test renaming diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -210,7 +210,7 @@ res = _pypyjson.loads('"z\\udc00\\udc00x"') assert list(res) == [u'z', u'\udc00', u'\udc00', u'x'] - def test_surrogate_pair(self): + def test_lone_surrogate(self): import _pypyjson json = '{"a":"\\uD83D"}' res = _pypyjson.loads(json) From pypy.commits at gmail.com Mon Apr 29 05:39:29 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:39:29 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge default Message-ID: <5cc6c651.1c69fb81.86d3d.6400@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96560:86dc760c19db Date: 2019-04-29 11:38 +0200 http://bitbucket.org/pypy/pypy/changeset/86dc760c19db/ Log: hg merge default diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1400,7 +1400,7 @@ s, pos, pos + 4) result.append(r) continue - elif ch >= 0x110000: + elif r_uint(ch) >= 0x110000: r, pos, rettype = errorhandler(errors, public_encoding_name, "codepoint not in range(0x110000)", s, pos, len(s)) diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -828,7 +828,7 @@ if not 0 <= x <= 0x10FFFF: raise oefmt(space.w_TypeError, "character mapping must be in range(0x110000)") - return rutf8.unichr_as_utf8(x) + return rutf8.unichr_as_utf8(x, allow_surrogates=True) elif space.is_w(w_ch, space.w_None): # Charmap may return None return errorchar diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -125,6 +125,7 @@ assert (charmap_decode(b"\x00\x01\x02", "strict", {0: u'\U0010FFFF', 1: u'b', 2: u'c'}) == (u"\U0010FFFFbc", 3)) + assert charmap_decode(b'\xff', "strict", {0xff: 0xd800}) == (u'\ud800', 1) def test_escape_decode(self): from _codecs import unicode_escape_decode as decode diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py --- a/pypy/module/_pypyjson/interp_decoder.py +++ b/pypy/module/_pypyjson/interp_decoder.py @@ -366,10 +366,14 @@ hexdigits = self.getslice(start, i) try: val = int(hexdigits, 16) - if sys.maxunicode > 65535 and 0xd800 <= val <= 0xdfff: - # surrogate pair - if self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u': - val = self.decode_surrogate_pair(i, val) + if (0xd800 <= val <= 0xdbff and + self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u'): + hexdigits = self.getslice(i+2, i+6) + lowsurr = int(hexdigits, 16) + if 0xdc00 <= lowsurr <= 0xdfff: + # decode surrogate pair + val = 0x10000 + (((val - 0xd800) << 10) | + (lowsurr - 0xdc00)) i += 6 except ValueError: raise DecoderError("Invalid \uXXXX escape (char %d)", i-1) @@ -380,15 +384,6 @@ builder.append(utf8_ch) return i - def decode_surrogate_pair(self, i, highsurr): - """ uppon enter the following must hold: - chars[i] == "\\" and chars[i+1] == "u" - """ - i += 2 - hexdigits = self.getslice(i, i+4) - lowsurr = int(hexdigits, 16) # the possible ValueError is caugth by the caller - return 0x10000 + (((highsurr - 0xd800) << 10) | (lowsurr - 0xdc00)) - def decode_key(self, i): """ returns a wrapped unicode """ from rpython.rlib.rarithmetic import intmask diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -198,6 +198,17 @@ res = _pypyjson.loads('"z\\ud834\\udd20x"') assert res == expected + def test_unicode_not_a_surrogate_pair(self): + import _pypyjson + res = _pypyjson.loads('"z\\ud800\\ud800x"') + assert list(res) == [u'z', u'\ud800', u'\ud800', u'x'] + res = _pypyjson.loads('"z\\udbff\\uffffx"') + assert list(res) == [u'z', u'\udbff', u'\uffff', u'x'] + res = _pypyjson.loads('"z\\ud800\\ud834\\udd20x"') + assert res == u'z\ud800\U0001d120x' + res = _pypyjson.loads('"z\\udc00\\udc00x"') + assert list(res) == [u'z', u'\udc00', u'\udc00', u'x'] + def test_lone_surrogate(self): import _pypyjson json = '{"a":"\\uD83D"}' diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -452,8 +452,13 @@ elif c == 'c': return space.newbytes(func(add_arg, argdesc, ll_type)) elif c == 'u': - return space.newutf8(rutf8.unichr_as_utf8( - r_uint(ord(func(add_arg, argdesc, ll_type)))), 1) + code = r_uint(ord(func(add_arg, argdesc, ll_type))) + try: + return space.newutf8(rutf8.unichr_as_utf8( + code, allow_surrogates=True), 1) + except rutf8.OutOfRange: + raise oefmt(space.w_ValueError, + "unicode character %d out of range", code) elif c == 'f' or c == 'd' or c == 'g': return space.newfloat(float(func(add_arg, argdesc, ll_type))) else: diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -348,6 +348,21 @@ arg2.free() a.free() + def test_unicode_array(self): + import _rawffi + A = _rawffi.Array('u') + a = A(6, u'\u1234') + assert a[0] == u'\u1234' + a[0] = u'\U00012345' + assert a[0] == u'\U00012345' + a[0] = u'\ud800' + assert a[0] == u'\ud800' + B = _rawffi.Array('i') + b = B.fromaddress(a.itemaddress(0), 1) + b[0] = 0xffffffff + raises(ValueError, "a[0]") + a.free() + def test_returning_unicode(self): import _rawffi A = _rawffi.Array('u') diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -1159,7 +1159,7 @@ elif mytype.typecode == 'u': code = r_uint(ord(item)) try: - item = rutf8.unichr_as_utf8(code) + item = rutf8.unichr_as_utf8(code, allow_surrogates=True) except rutf8.OutOfRange: raise oefmt(space.w_ValueError, "cannot operate on this array('u') because it contains" diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -917,6 +917,10 @@ assert a.tounicode() == input_unicode raises(ValueError, b.tounicode) # doesn't work + def test_unicode_surrogate(self): + a = self.array('u', u'\ud800') + assert a[0] == u'\ud800' + def test_weakref(self): import weakref a = self.array('u', 'Hi!') diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -326,7 +326,8 @@ space = self.space if do_unicode: cp = rutf8.codepoint_at_pos(self.fmt, self.fmtpos - 1) - w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp)), 1) + w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp), + allow_surrogates=True), 1) else: cp = ord(self.fmt[self.fmtpos - 1]) w_s = space.newbytes(chr(cp)) @@ -478,7 +479,8 @@ n = space.int_w(w_value) if do_unicode: try: - c = rutf8.unichr_as_utf8(r_uint(n)) + c = rutf8.unichr_as_utf8(r_uint(n), + allow_surrogates=True) except rutf8.OutOfRange: raise oefmt(space.w_OverflowError, "unicode character code out of range") diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -357,9 +357,11 @@ if recursive: spec = self._build_string(spec_start, end, level) w_rendered = self.space.format(w_obj, self.wrap(spec)) - unwrapper = "utf8_w" if self.is_unicode else "bytes_w" - to_interp = getattr(self.space, unwrapper) - return to_interp(w_rendered) + if self.is_unicode: + w_rendered = self.space.unicode_from_object(w_rendered) + return self.space.utf8_w(w_rendered) + else: + return self.space.bytes_w(w_rendered) def formatter_parser(self): self.parser_list_w = [] diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -245,6 +245,7 @@ def test_simple(self): assert format(self.i(2)) == "2" assert isinstance(format(self.i(2), ""), str) + assert isinstance(self.i(2).__format__(""), str) def test_invalid(self): raises(ValueError, format, self.i(8), "s") @@ -491,3 +492,9 @@ excinfo = raises(ValueError, "{:j}".format, x(1)) print(excinfo.value) assert str(excinfo.value) == "Unknown format code j for object of type 'x'" + + def test_format_char(self): + import sys + assert '{0:c}'.format(42) == '*' + assert '{0:c}'.format(1234) == '\u04d2' + raises(OverflowError, '{0:c}'.format, -1) diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py --- a/pypy/objspace/std/test/test_stringformat.py +++ b/pypy/objspace/std/test/test_stringformat.py @@ -215,6 +215,7 @@ def test_format_wrong_char(self): raises(ValueError, 'a%Zb'.__mod__, ((23,),)) + raises(ValueError, u'a%\ud800b'.__mod__, ((23,),)) def test_incomplete_format(self): raises(ValueError, '%'.__mod__, ((23,),)) @@ -234,6 +235,8 @@ raises(TypeError, '%c'.__mod__, ("",)) raises(TypeError, '%c'.__mod__, (['c'],)) raises(TypeError, '%c'.__mod__, b'A') + surrogate = 0xd800 + assert '%c' % surrogate == '\ud800' def test___int__index__(self): class MyInt(object): diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -1180,8 +1180,7 @@ def test_format_repeat(self): assert format(u"abc", u"z<5") == u"abczz" assert format(u"abc", u"\u2007<5") == u"abc\u2007\u2007" - #CPython2 raises UnicodeEncodeError - assert format(123, u"\u2007<5") == u"123\u2007\u2007" + assert format(123, "\u2007<5") == "123\u2007\u2007" def test_formatting_unicode__repr__(self): # Printable character diff --git a/pypy/tool/release/force-builds.py b/pypy/tool/release/force-builds.py --- a/pypy/tool/release/force-builds.py +++ b/pypy/tool/release/force-builds.py @@ -8,8 +8,13 @@ modified by PyPy team """ +from __future__ import absolute_import, division, print_function -import os, sys, urllib, subprocess +import os, sys, subprocess +try: + from urllib2 import quote +except ImportError: + from urllib.request import quote from twisted.internet import reactor, defer from twisted.python import log @@ -29,10 +34,10 @@ 'pypy-c-jit-macosx-x86-64', 'pypy-c-jit-win-x86-32', 'pypy-c-jit-linux-s390x', - 'build-pypy-c-jit-linux-armhf-raspbian', - 'build-pypy-c-jit-linux-armel', +# 'build-pypy-c-jit-linux-armhf-raspbian', +# 'build-pypy-c-jit-linux-armel', 'rpython-linux-x86-32', - 'rpython-linux-x86-64' + 'rpython-linux-x86-64', 'rpython-win-x86-32' ] @@ -54,7 +59,7 @@ log.err(err, "Build force failure") for builder in BUILDERS: - print 'Forcing', builder, '...' + print('Forcing', builder, '...') url = "http://" + server + "/builders/" + builder + "/force" args = [ ('username', user), @@ -63,15 +68,15 @@ ('submit', 'Force Build'), ('branch', branch), ('comments', "Forced by command line script")] - url = url + '?' + '&'.join([k + '=' + urllib.quote(v) for (k, v) in args]) + url = url + '?' + '&'.join([k + '=' + quote(v) for (k, v) in args]) requests.append( - lock.run(client.getPage, url, followRedirect=False).addErrback(ebList)) + lock.run(client.getPage, url.encode('utf-8'), followRedirect=False).addErrback(ebList)) d = defer.gatherResults(requests) d.addErrback(log.err) d.addCallback(lambda ign: reactor.stop()) reactor.run() - print 'See http://buildbot.pypy.org/summary after a while' + print('See http://buildbot.pypy.org/summary after a while') if __name__ == '__main__': log.startLogging(sys.stdout) @@ -86,6 +91,6 @@ try: subprocess.check_call(['hg','id','-r', options.branch]) except subprocess.CalledProcessError: - print 'branch', options.branch, 'could not be found in local repository' + print('branch', options.branch, 'could not be found in local repository') sys.exit(-1) main(options.branch, options.server, user=options.user) From pypy.commits at gmail.com Mon Apr 29 05:39:31 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:39:31 -0700 (PDT) Subject: [pypy-commit] pypy default: detail Message-ID: <5cc6c653.1c69fb81.f8db4.c761@mx.google.com> Author: Armin Rigo Branch: Changeset: r96561:9b18230035ef Date: 2019-04-29 11:38 +0200 http://bitbucket.org/pypy/pypy/changeset/9b18230035ef/ Log: detail diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -450,7 +450,7 @@ elif c == 'c': return space.newbytes(func(add_arg, argdesc, ll_type)) elif c == 'u': - code = ord(func(add_arg, argdesc, ll_type)) + code = r_uint(ord(func(add_arg, argdesc, ll_type))) try: return space.newutf8(rutf8.unichr_as_utf8( code, allow_surrogates=True), 1) From pypy.commits at gmail.com Mon Apr 29 05:39:33 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 29 Apr 2019 02:39:33 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge default Message-ID: <5cc6c655.1c69fb81.c81a.c34f@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96562:86f5da78e2fc Date: 2019-04-29 11:38 +0200 http://bitbucket.org/pypy/pypy/changeset/86f5da78e2fc/ Log: hg merge default From pypy.commits at gmail.com Tue Apr 30 09:42:49 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 30 Apr 2019 06:42:49 -0700 (PDT) Subject: [pypy-commit] pypy semlock-deadlock: document, close branch to be merged Message-ID: <5cc850d9.1c69fb81.c3759.7c4b@mx.google.com> Author: Matti Picus Branch: semlock-deadlock Changeset: r96565:7c3fc68b2a9e Date: 2019-04-30 09:30 -0400 http://bitbucket.org/pypy/pypy/changeset/7c3fc68b2a9e/ Log: document, close branch to be merged diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -16,3 +16,8 @@ .. branch: datetime_api_27 Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` + +.. branch: semlock-deadlock + +Test and reduce the probability of a deadlock when acquiring a semaphore by +moving global state changes closer to the actual aquire. From pypy.commits at gmail.com Tue Apr 30 09:42:51 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 30 Apr 2019 06:42:51 -0700 (PDT) Subject: [pypy-commit] pypy default: fix semaphore deadlock in issue 2953 Message-ID: <5cc850db.1c69fb81.b42bb.8193@mx.google.com> Author: Matti Picus Branch: Changeset: r96566:6187f28f2baf Date: 2019-04-30 09:32 -0400 http://bitbucket.org/pypy/pypy/changeset/6187f28f2baf/ Log: fix semaphore deadlock in issue 2953 diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -16,3 +16,8 @@ .. branch: datetime_api_27 Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp`` + +.. branch: semlock-deadlock + +Test and reduce the probability of a deadlock when acquiring a semaphore by +moving global state changes closer to the actual aquire. diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -46,7 +46,8 @@ eci = ExternalCompilationInfo( includes = ['sys/time.h', 'limits.h', - 'semaphore.h'], + 'semaphore.h', + ], libraries = libraries, ) @@ -259,6 +260,8 @@ res = rwin32.WaitForSingleObject(self.handle, 0) if res != rwin32.WAIT_TIMEOUT: + self.last_tid = rthread.get_ident() + self.count += 1 return True msecs = full_msecs @@ -291,6 +294,8 @@ # handle result if res != rwin32.WAIT_TIMEOUT: + self.last_tid = rthread.get_ident() + self.count += 1 return True return False @@ -369,8 +374,9 @@ elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT): return False raise - _check_signals(space) - + _check_signals(space) + self.last_tid = rthread.get_ident() + self.count += 1 return True finally: if deadline: @@ -439,6 +445,7 @@ self.count = 0 self.maxvalue = maxvalue self.register_finalizer(space) + self.last_tid = -1 def kind_get(self, space): return space.newint(self.kind) @@ -476,15 +483,15 @@ if self.kind == RECURSIVE_MUTEX and self._ismine(): self.count += 1 return space.w_True - try: + # sets self.last_tid and increments self.count + # those steps need to be as close as possible to + # acquiring the semlock for self._ismine() to support + # multiple threads got = semlock_acquire(self, space, block, w_timeout) except OSError as e: raise wrap_oserror(space, e) - if got: - self.last_tid = rthread.get_ident() - self.count += 1 return space.w_True else: return space.w_False @@ -501,10 +508,10 @@ try: semlock_release(self, space) + self.count -= 1 except OSError as e: raise wrap_oserror(space, e) - self.count -= 1 def after_fork(self): self.count = 0 diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -17,6 +17,7 @@ def setup_class(cls): cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE) cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def test_semaphore(self): from _multiprocessing import SemLock @@ -108,3 +109,25 @@ with sem: assert sem._count() == 1 assert sem._count() == 0 + + def test_in_threads(self): + from _multiprocessing import SemLock + from threading import Thread + from time import sleep + l = SemLock(0, 1, 1) + if self.runappdirect: + def f(id): + for i in range(10000): + pass + else: + def f(id): + for i in range(1000): + # reduce the probability of thread switching + # at exactly the wrong time in semlock_acquire + for j in range(10): + pass + threads = [Thread(None, f, args=(i,)) for i in range(2)] + [t.start() for t in threads] + # if the RLock calls to sem_wait and sem_post do not match, + # one of the threads will block and the call to join will fail + [t.join() for t in threads] From pypy.commits at gmail.com Tue Apr 30 09:42:53 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 30 Apr 2019 06:42:53 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: merge default into py3.6 Message-ID: <5cc850dd.1c69fb81.b5510.af63@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96567:777ad5f524c1 Date: 2019-04-30 09:34 -0400 http://bitbucket.org/pypy/pypy/changeset/777ad5f524c1/ Log: merge default into py3.6 diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -20,3 +20,8 @@ .. branch: issue2968 Fix segfault in cpyext_tp_new_tupl + +.. branch: semlock-deadlock + +Test and reduce the probability of a deadlock when acquiring a semaphore by +moving global state changes closer to the actual aquire. diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -49,7 +49,8 @@ eci = ExternalCompilationInfo( includes = ['sys/time.h', 'limits.h', - 'semaphore.h'], + 'semaphore.h', + ], libraries = libraries, ) @@ -269,6 +270,8 @@ res = rwin32.WaitForSingleObject(self.handle, 0) if res != rwin32.WAIT_TIMEOUT: + self.last_tid = rthread.get_ident() + self.count += 1 return True msecs = full_msecs @@ -301,6 +304,8 @@ # handle result if res != rwin32.WAIT_TIMEOUT: + self.last_tid = rthread.get_ident() + self.count += 1 return True return False @@ -379,8 +384,9 @@ elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT): return False raise - _check_signals(space) - + _check_signals(space) + self.last_tid = rthread.get_ident() + self.count += 1 return True finally: if deadline: @@ -449,6 +455,7 @@ self.count = 0 self.maxvalue = maxvalue self.register_finalizer(space) + self.last_tid = -1 self.name = name def name_get(self, space): @@ -495,15 +502,15 @@ if self.kind == RECURSIVE_MUTEX and self._ismine(): self.count += 1 return space.w_True - try: + # sets self.last_tid and increments self.count + # those steps need to be as close as possible to + # acquiring the semlock for self._ismine() to support + # multiple threads got = semlock_acquire(self, space, block, w_timeout) except OSError as e: raise wrap_oserror(space, e) - if got: - self.last_tid = rthread.get_ident() - self.count += 1 return space.w_True else: return space.w_False @@ -520,10 +527,10 @@ try: semlock_release(self, space) + self.count -= 1 except OSError as e: raise wrap_oserror(space, e) - self.count -= 1 def after_fork(self): self.count = 0 diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -18,6 +18,7 @@ def setup_class(cls): cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE) cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) @py.test.mark.skipif("sys.platform == 'win32'") def test_sem_unlink(self): @@ -138,3 +139,25 @@ from _multiprocessing import SemLock sem = SemLock(self.SEMAPHORE, 1, 1, '/mp-123', unlink=True) assert sem._count() == 0 + + def test_in_threads(self): + from _multiprocessing import SemLock + from threading import Thread + from time import sleep + l = SemLock(0, 1, 1) + if self.runappdirect: + def f(id): + for i in range(10000): + pass + else: + def f(id): + for i in range(1000): + # reduce the probability of thread switching + # at exactly the wrong time in semlock_acquire + for j in range(10): + pass + threads = [Thread(None, f, args=(i,)) for i in range(2)] + [t.start() for t in threads] + # if the RLock calls to sem_wait and sem_post do not match, + # one of the threads will block and the call to join will fail + [t.join() for t in threads] From pypy.commits at gmail.com Tue Apr 30 09:42:55 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 30 Apr 2019 06:42:55 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix test for python3 Message-ID: <5cc850df.1c69fb81.26b66.9999@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r96568:60d99c821291 Date: 2019-04-30 09:41 -0400 http://bitbucket.org/pypy/pypy/changeset/60d99c821291/ Log: fix test for python3 diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -144,7 +144,7 @@ from _multiprocessing import SemLock from threading import Thread from time import sleep - l = SemLock(0, 1, 1) + l = SemLock(0, 1, 1, "6", unlink=True) if self.runappdirect: def f(id): for i in range(10000): From pypy.commits at gmail.com Tue Apr 30 13:13:01 2019 From: pypy.commits at gmail.com (antocuni) Date: Tue, 30 Apr 2019 10:13:01 -0700 (PDT) Subject: [pypy-commit] pyrepl default: remove trailing whitespace Message-ID: <5cc8821d.1c69fb81.5e329.20a0@mx.google.com> Author: Antonio Cuni Branch: Changeset: r272:ee97ef7ab45d Date: 2019-04-30 19:12 +0200 http://bitbucket.org/pypy/pyrepl/changeset/ee97ef7ab45d/ Log: remove trailing whitespace diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -217,7 +217,7 @@ if self.stderr and hasattr(self.stderr, 'flush'): self.stderr.flush() - reader.ps1 = prompt + reader.ps1 = prompt return reader.readline(startup_hook=self.startup_hook) def multiline_input(self, more_lines, ps1, ps2, returns_unicode=False):