Author: mattip <matti.pi...@gmail.com> Branch: cpyext-ext Changeset: r82421:0b974f24de3d Date: 2016-02-23 11:14 +0100 http://bitbucket.org/pypy/pypy/changeset/0b974f24de3d/
Log: merge cpyext-gc-support-2 into branch diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -22,6 +22,7 @@ ^pypy/module/cpyext/test/.+\.obj$ ^pypy/module/cpyext/test/.+\.manifest$ ^pypy/module/test_lib_pypy/ctypes_tests/.+\.o$ +^pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test\.o$ ^pypy/module/cppyy/src/.+\.o$ ^pypy/module/cppyy/bench/.+\.so$ ^pypy/module/cppyy/bench/.+\.root$ @@ -35,7 +36,6 @@ ^pypy/module/test_lib_pypy/cffi_tests/__pycache__.+$ ^pypy/doc/.+\.html$ ^pypy/doc/config/.+\.rst$ -^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ ^rpython/translator/c/src/libffi_msvc/.+\.obj$ ^rpython/translator/c/src/libffi_msvc/.+\.dll$ @@ -45,53 +45,33 @@ ^rpython/translator/c/src/cjkcodecs/.+\.obj$ ^rpython/translator/c/src/stacklet/.+\.o$ ^rpython/translator/c/src/.+\.o$ -^rpython/translator/jvm/\.project$ -^rpython/translator/jvm/\.classpath$ -^rpython/translator/jvm/eclipse-bin$ -^rpython/translator/jvm/src/pypy/.+\.class$ -^rpython/translator/benchmark/docutils$ -^rpython/translator/benchmark/templess$ -^rpython/translator/benchmark/gadfly$ -^rpython/translator/benchmark/mako$ -^rpython/translator/benchmark/bench-custom\.benchmark_result$ -^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/llvm/.+\.so$ ^rpython/translator/goal/target.+-c$ ^rpython/translator/goal/.+\.exe$ ^rpython/translator/goal/.+\.dll$ ^pypy/goal/pypy-translation-snapshot$ ^pypy/goal/pypy-c -^pypy/goal/pypy-jvm -^pypy/goal/pypy-jvm.jar ^pypy/goal/.+\.exe$ ^pypy/goal/.+\.dll$ ^pypy/goal/.+\.lib$ ^pypy/_cache$ -^pypy/doc/statistic/.+\.html$ -^pypy/doc/statistic/.+\.eps$ -^pypy/doc/statistic/.+\.pdf$ -^rpython/translator/cli/src/pypylib\.dll$ -^rpython/translator/cli/src/query\.exe$ -^rpython/translator/cli/src/main\.exe$ +^lib-python/2.7/lib2to3/.+\.pickle$ ^lib_pypy/__pycache__$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ ^lib_pypy/_libmpdec/.+.o$ -^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ ^pypy/doc/_build/.*$ ^pypy/doc/config/.+\.html$ ^pypy/doc/config/style\.css$ -^pypy/doc/jit/.+\.html$ -^pypy/doc/jit/style\.css$ ^pypy/doc/image/lattice1\.png$ ^pypy/doc/image/lattice2\.png$ ^pypy/doc/image/lattice3\.png$ ^pypy/doc/image/stackless_informal\.png$ ^pypy/doc/image/parsing_example.+\.png$ ^rpython/doc/_build/.*$ -^pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test\.o$ ^compiled ^.git/ ^release/ diff --git a/pypy/interpreter/pyparser/pytokenizer.py b/pypy/interpreter/pyparser/pytokenizer.py --- a/pypy/interpreter/pyparser/pytokenizer.py +++ b/pypy/interpreter/pyparser/pytokenizer.py @@ -91,6 +91,7 @@ strstart = (0, 0, "") for line in lines: lnum = lnum + 1 + line = universal_newline(line) pos, max = 0, len(line) if contstr: @@ -259,3 +260,14 @@ token_list.append((tokens.ENDMARKER, '', lnum, pos, line)) return token_list + + +def universal_newline(line): + # show annotator that indexes below are non-negative + line_len_m2 = len(line) - 2 + if line_len_m2 >= 0 and line[-2] == '\r' and line[-1] == '\n': + return line[:line_len_m2] + '\n' + line_len_m1 = len(line) - 1 + if line_len_m1 >= 0 and line[-1] == '\r': + return line[:line_len_m1] + '\n' + return line diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py b/pypy/interpreter/pyparser/test/test_pyparse.py --- a/pypy/interpreter/pyparser/test/test_pyparse.py +++ b/pypy/interpreter/pyparser/test/test_pyparse.py @@ -158,3 +158,10 @@ def test_print_function(self): self.parse("from __future__ import print_function\nx = print\n") + + def test_universal_newlines(self): + fmt = 'stuff = """hello%sworld"""' + expected_tree = self.parse(fmt % '\n') + for linefeed in ["\r\n","\r"]: + tree = self.parse(fmt % linefeed) + assert expected_tree == tree diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -156,20 +156,6 @@ get_unique_interplevel_subclass._annspecialcase_ = "specialize:memo" _subclass_cache = {} -def enum_interplevel_subclasses(config, cls): - """Return a list of all the extra interp-level subclasses of 'cls' that - can be built by get_unique_interplevel_subclass().""" - result = [] - for flag1 in (False, True): - for flag2 in (False, True): - for flag3 in (False, True): - for flag4 in (False, True): - result.append(get_unique_interplevel_subclass( - config, cls, flag1, flag2, flag3, flag4)) - result = dict.fromkeys(result) - assert len(result) <= 6 - return result.keys() - def _getusercls(config, cls, wants_dict, wants_slots, wants_del, weakrefable): typedef = cls.typedef if wants_dict and typedef.hasdict: @@ -262,7 +248,7 @@ def user_setup(self, space, w_subtype): self.space = space self.w__class__ = w_subtype - self.user_setup_slots(w_subtype.nslots) + self.user_setup_slots(w_subtype.layout.nslots) def user_setup_slots(self, nslots): assert nslots == 0 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 @@ -945,7 +945,7 @@ py_obj = static_pyobjs[i] w_obj = static_objs_w[i] w_type = space.type(w_obj) - typedescr = get_typedescr(w_type.instancetypedef) + typedescr = get_typedescr(w_type.layout.typedef) py_obj.c_ob_type = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type)) typedescr.attach(space, py_obj, w_obj) @@ -1144,7 +1144,7 @@ if not use_micronumpy: return use_micronumpy # import to register api functions by side-effect - import pypy.module.cpyext.ndarrayobject + import pypy.module.cpyext.ndarrayobject global GLOBALS, SYMBOLS_C, separate_module_files GLOBALS["PyArray_Type#"]= ('PyTypeObject*', "space.gettypeobject(W_NDimArray.typedef)") SYMBOLS_C += ['PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS'] diff --git a/pypy/module/cpyext/bufferobject.py b/pypy/module/cpyext/bufferobject.py --- a/pypy/module/cpyext/bufferobject.py +++ b/pypy/module/cpyext/bufferobject.py @@ -25,7 +25,7 @@ @bootstrap_function def init_bufferobject(space): "Type description of PyBufferObject" - make_typedescr(space.w_buffer.instancetypedef, + make_typedescr(space.w_buffer.layout.typedef, basestruct=PyBufferObject.TO, attach=buffer_attach, dealloc=buffer_dealloc, diff --git a/pypy/module/cpyext/floatobject.py b/pypy/module/cpyext/floatobject.py --- a/pypy/module/cpyext/floatobject.py +++ b/pypy/module/cpyext/floatobject.py @@ -17,7 +17,7 @@ @bootstrap_function def init_floatobject(space): "Type description of PyFloatObject" - make_typedescr(space.w_float.instancetypedef, + make_typedescr(space.w_float.layout.typedef, basestruct=PyFloatObject.TO, attach=float_attach, realize=float_realize) diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py --- a/pypy/module/cpyext/intobject.py +++ b/pypy/module/cpyext/intobject.py @@ -19,7 +19,7 @@ @bootstrap_function def init_intobject(space): "Type description of PyIntObject" - make_typedescr(space.w_int.instancetypedef, + make_typedescr(space.w_int.layout.typedef, basestruct=PyIntObject.TO, attach=int_attach, realize=int_realize) @@ -51,7 +51,7 @@ @cpython_api([lltype.Signed], PyObject) def PyInt_FromLong(space, ival): """Create a new integer object with a value of ival. - + """ return space.wrap(ival) diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -31,7 +31,7 @@ def _PyObject_NewVar(space, type, itemcount): w_type = from_ref(space, rffi.cast(PyObject, type)) assert isinstance(w_type, W_TypeObject) - typedescr = get_typedescr(w_type.instancetypedef) + typedescr = get_typedescr(w_type.layout.typedef) py_obj = typedescr.allocate(space, w_type, itemcount=itemcount) #py_obj.c_ob_refcnt = 0 --- will be set to 1 again by PyObject_Init{Var} if type.c_tp_itemsize == 0: diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py --- a/pypy/module/cpyext/pyobject.py +++ b/pypy/module/cpyext/pyobject.py @@ -115,7 +115,7 @@ def init_pyobject(space): from pypy.module.cpyext.object import PyObject_dealloc # typedescr for the 'object' type - make_typedescr(space.w_object.instancetypedef, + make_typedescr(space.w_object.layout.typedef, dealloc=PyObject_dealloc) # almost all types, which should better inherit from object. make_typedescr(None) @@ -207,7 +207,7 @@ raise InvalidPointerException(str(ref)) w_type = from_ref(space, ref_type) assert isinstance(w_type, W_TypeObject) - return get_typedescr(w_type.instancetypedef).realize(space, ref) + return get_typedescr(w_type.layout.typedef).realize(space, ref) def debug_collect(): @@ -327,7 +327,7 @@ obj.c_ob_refcnt = 1 w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type)) assert isinstance(w_type, W_TypeObject) - get_typedescr(w_type.instancetypedef).realize(space, obj) + get_typedescr(w_type.layout.typedef).realize(space, obj) @cpython_api([PyObject], lltype.Void) def _Py_Dealloc(space, obj): diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py --- a/pypy/module/cpyext/stringobject.py +++ b/pypy/module/cpyext/stringobject.py @@ -60,7 +60,7 @@ @bootstrap_function def init_stringobject(space): "Type description of PyStringObject" - make_typedescr(space.w_str.instancetypedef, + make_typedescr(space.w_str.layout.typedef, basestruct=PyStringObject.TO, attach=string_attach, dealloc=string_dealloc, @@ -74,7 +74,7 @@ interpreter object. The buffer may be mutated, until string_realize() is called. Refcount of the result is 1. """ - typedescr = get_typedescr(space.w_str.instancetypedef) + typedescr = get_typedescr(space.w_str.layout.typedef) py_obj = typedescr.allocate(space, space.w_str) py_str = rffi.cast(PyStringObject, py_obj) diff --git a/pypy/module/cpyext/test/foo.c b/pypy/module/cpyext/test/foo.c --- a/pypy/module/cpyext/test/foo.c +++ b/pypy/module/cpyext/test/foo.c @@ -736,12 +736,18 @@ Py_RETURN_NONE; } +static PyObject *size_of_instances(PyObject *self, PyObject *t) +{ + return PyInt_FromLong(((PyTypeObject *)t)->tp_basicsize); +} + /* List of functions exported by this module */ static PyMethodDef foo_functions[] = { {"new", (PyCFunction)foo_new, METH_NOARGS, NULL}, {"newCustom", (PyCFunction)newCustom, METH_NOARGS, NULL}, {"cmp_docstring", (PyCFunction)cmp_docstring, METH_VARARGS, NULL}, + {"size_of_instances", (PyCFunction)size_of_instances, METH_O, NULL}, {NULL, NULL} /* Sentinel */ }; diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -725,8 +725,8 @@ static PyObject* foo_pi(PyObject* self, PyObject *args) { PyObject *true_obj = Py_True; - int refcnt = true_obj->ob_refcnt; - int refcnt_after; + Py_ssize_t refcnt = true_obj->ob_refcnt; + Py_ssize_t refcnt_after; Py_INCREF(true_obj); Py_INCREF(true_obj); PyBool_Check(true_obj); @@ -740,8 +740,8 @@ { PyObject *true_obj = Py_True; PyObject *tup = NULL; - int refcnt = true_obj->ob_refcnt; - int refcnt_after; + Py_ssize_t refcnt = true_obj->ob_refcnt; + Py_ssize_t refcnt_after; tup = PyTuple_New(1); Py_INCREF(true_obj); diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -766,3 +766,25 @@ module = self.import_module(name='foo3') print('calling module.Type()...') module.Type("X", (object,), {}) + + def test_app_subclass_of_c_type(self): + module = self.import_module(name='foo') + size = module.size_of_instances(module.fooType) + class f1(object): + pass + class f2(module.fooType): + pass + class bar(f1, f2): + pass + assert bar.__base__ is f2 + assert module.size_of_instances(bar) == size + + def test_app_cant_subclass_two_types(self): + module = self.import_module(name='foo') + try: + class bar(module.fooType, module.Property): + pass + except TypeError as e: + assert str(e) == 'instance layout conflicts in multiple inheritance' + else: + raise AssertionError("did not get TypeError!") diff --git a/pypy/module/cpyext/tupleobject.py b/pypy/module/cpyext/tupleobject.py --- a/pypy/module/cpyext/tupleobject.py +++ b/pypy/module/cpyext/tupleobject.py @@ -35,7 +35,7 @@ @bootstrap_function def init_stringobject(space): "Type description of PyTupleObject" - make_typedescr(space.w_tuple.instancetypedef, + make_typedescr(space.w_tuple.layout.typedef, basestruct=PyTupleObject.TO, attach=tuple_attach, dealloc=tuple_dealloc, @@ -54,7 +54,7 @@ corresponding interpreter object. The array may be mutated, until tuple_realize() is called. Refcount of the result is 1. """ - typedescr = get_typedescr(space.w_tuple.instancetypedef) + typedescr = get_typedescr(space.w_tuple.layout.typedef) py_obj = typedescr.allocate(space, space.w_tuple) py_tup = rffi.cast(PyTupleObject, py_obj) diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -197,7 +197,7 @@ def update_all_slots(space, w_type, pto): # XXX fill slots in pto - typedef = w_type.instancetypedef + typedef = w_type.layout.typedef for method_name, slot_name, slot_names, slot_func in slotdefs_for_tp_slots: w_descr = w_type.lookup(method_name) if w_descr is None: @@ -378,7 +378,7 @@ name = rffi.charp2str(pto.c_tp_name) W_TypeObject.__init__(self, space, name, - bases_w or [space.w_object], dict_w) + bases_w or [space.w_object], dict_w, force_new_layout=True) if not space.is_true(space.issubtype(self, space.w_type)): self.flag_cpytype = True self.flag_heaptype = False @@ -387,7 +387,7 @@ @bootstrap_function def init_typeobject(space): - make_typedescr(space.w_type.instancetypedef, + make_typedescr(space.w_type.layout.typedef, basestruct=PyTypeObject, alloc=type_alloc, attach=type_attach, @@ -525,7 +525,7 @@ pto = rffi.cast(PyTypeObjectPtr, py_obj) - typedescr = get_typedescr(w_type.instancetypedef) + typedescr = get_typedescr(w_type.layout.typedef) # dealloc pto.c_tp_dealloc = typedescr.get_dealloc(space) @@ -597,13 +597,13 @@ return w_obj def solid_base(space, w_type): - typedef = w_type.instancetypedef + typedef = w_type.layout.typedef return space.gettypeobject(typedef) def best_base(space, bases_w): if not bases_w: return None - return find_best_base(space, bases_w) + return find_best_base(bases_w) def inherit_slots(space, pto, w_base): # XXX missing: nearly everything diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -28,7 +28,7 @@ @bootstrap_function def init_unicodeobject(space): - make_typedescr(space.w_unicode.instancetypedef, + make_typedescr(space.w_unicode.layout.typedef, basestruct=PyUnicodeObject.TO, attach=unicode_attach, dealloc=unicode_dealloc, @@ -49,7 +49,7 @@ interpreter object. The buffer may be mutated, until unicode_realize() is called. Refcount of the result is 1. """ - typedescr = get_typedescr(space.w_unicode.instancetypedef) + typedescr = get_typedescr(space.w_unicode.layout.typedef) py_obj = typedescr.allocate(space, space.w_unicode) py_uni = rffi.cast(PyUnicodeObject, py_obj) diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -196,6 +196,10 @@ def newfloat(self, f): return self.float(f) + def newslice(self, start, stop, step): + return SliceObject(self.int_w(start), self.int_w(stop), + self.int_w(step)) + def le(self, w_obj1, w_obj2): assert isinstance(w_obj1, boxes.W_GenericBox) assert isinstance(w_obj2, boxes.W_GenericBox) diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -94,11 +94,13 @@ dim = i break if dim >= 0: - # filter by axis r - filtr = chunks.pop(dim) + # filter by axis dim + filtr = chunks[dim] assert isinstance(filtr, BooleanChunk) w_arr = w_arr.getitem_filter(space, filtr.w_idx, axis=dim) arr = w_arr.implementation + chunks[dim] = SliceChunk(space.newslice(space.wrap(0), + space.wrap(-1), space.w_None)) r = calculate_slice_strides(space, arr.shape, arr.start, arr.get_strides(), arr.get_backstrides(), chunks) else: diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py --- a/pypy/module/micronumpy/test/test_ndarray.py +++ b/pypy/module/micronumpy/test/test_ndarray.py @@ -2550,6 +2550,8 @@ assert b.base is None b = a[:, np.array([True, False, True])] assert b.base is not None + b = a[np.array([True, False]), 0] + assert (b ==[0]).all() def test_scalar_indexing(self): import numpy as np 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 @@ -359,7 +359,8 @@ subcls = get_subclass_of_correct_size(self, cls, w_subtype) else: subcls = get_unique_interplevel_subclass( - self.config, cls, w_subtype.hasdict, w_subtype.nslots != 0, + self.config, cls, w_subtype.hasdict, + w_subtype.layout.nslots != 0, w_subtype.needsdel, w_subtype.weakrefable) instance = instantiate(subcls) assert isinstance(instance, cls) diff --git a/pypy/objspace/std/transparent.py b/pypy/objspace/std/transparent.py --- a/pypy/objspace/std/transparent.py +++ b/pypy/objspace/std/transparent.py @@ -62,7 +62,7 @@ return W_TransparentGenerator(space, w_type, w_controller) if space.is_true(space.issubtype(w_type, space.gettypeobject(PyCode.typedef))): return W_TransparentCode(space, w_type, w_controller) - if w_type.instancetypedef is space.w_object.instancetypedef: + if w_type.layout.typedef is space.w_object.layout.typedef: return W_Transparent(space, w_type, w_controller) else: raise OperationError(space.w_TypeError, space.wrap("type expected as first argument")) 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 @@ -7,7 +7,7 @@ from pypy.interpreter.astcompiler.misc import mangle from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, - promote_string, elidable, dont_look_inside, unroll_safe) + elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash from rpython.rlib.rarithmetic import intmask, r_uint @@ -87,6 +87,29 @@ for i in range(len(self.lookup_where)): self.lookup_where[i] = None_None + +class Layout(object): + """A Layout is attached to every W_TypeObject to represent the + layout of instances. Some W_TypeObjects share the same layout. + If a W_TypeObject is a base of another, then the layout of + the first is either the same or a parent layout of the second. + The Layouts have single inheritance, unlike W_TypeObjects. + """ + _immutable_ = True + + def __init__(self, typedef, nslots, base_layout=None): + self.typedef = typedef + self.nslots = nslots + self.base_layout = base_layout + + def issublayout(self, parent): + while self is not parent: + self = self.base_layout + if self is None: + return False + return True + + # possible values of compares_by_identity_status UNKNOWN = 0 COMPARES_BY_IDENTITY = 1 @@ -106,8 +129,7 @@ 'needsdel', 'weakrefable', 'hasdict', - 'nslots', - 'instancetypedef', + 'layout', 'terminator', '_version_tag?', 'name?', @@ -126,12 +148,11 @@ @dont_look_inside def __init__(w_self, space, name, bases_w, dict_w, - overridetypedef=None): + overridetypedef=None, force_new_layout=False): w_self.space = space w_self.name = name w_self.bases_w = bases_w w_self.dict_w = dict_w - w_self.nslots = 0 w_self.hasdict = False w_self.needsdel = False w_self.weakrefable = False @@ -141,13 +162,13 @@ w_self.flag_cpytype = False w_self.flag_abstract = False w_self.flag_sequence_bug_compat = False - w_self.instancetypedef = overridetypedef if overridetypedef is not None: - setup_builtin_type(w_self) + assert not force_new_layout + layout = setup_builtin_type(w_self, overridetypedef) else: - setup_user_defined_type(w_self) - w_self.w_same_layout_as = get_parent_layout(w_self) + layout = setup_user_defined_type(w_self, force_new_layout) + w_self.layout = layout if space.config.objspace.std.withtypeversion: if not is_mro_purely_of_types(w_self.mro_w): @@ -268,8 +289,8 @@ # compute a tuple that fully describes the instance layout def get_full_instance_layout(w_self): - w_layout = w_self.w_same_layout_as or w_self - return (w_layout, w_self.hasdict, w_self.needsdel, w_self.weakrefable) + layout = w_self.layout + return (layout, w_self.hasdict, w_self.needsdel, w_self.weakrefable) def compute_default_mro(w_self): return compute_C3_mro(w_self.space, w_self) @@ -406,7 +427,6 @@ if version_tag is None: tup = w_self._lookup_where(name) return tup - name = promote_string(name) tup_w = w_self._pure_lookup_where_with_method_cache(name, version_tag) w_class, w_value = tup_w if (space.config.objspace.std.withtypeversion and @@ -467,7 +487,7 @@ raise oefmt(space.w_TypeError, "%N.__new__(%N): %N is not a subtype of %N", w_self, w_subtype, w_subtype, w_self) - if w_self.instancetypedef is not w_subtype.instancetypedef: + if w_self.layout.typedef is not w_subtype.layout.typedef: raise oefmt(space.w_TypeError, "%N.__new__(%N) is not safe, use %N.__new__()", w_self, w_subtype, w_subtype) @@ -821,11 +841,10 @@ for w_subclass in w_type.get_subclasses(): if isinstance(w_subclass, W_TypeObject): w_subclass._version_tag = None - assert w_type.w_same_layout_as is get_parent_layout(w_type) # invariant def descr__base(space, w_type): w_type = _check(space, w_type) - return find_best_base(space, w_type.bases_w) + return find_best_base(w_type.bases_w) def descr__doc(space, w_type): if space.is_w(w_type, space.w_type): @@ -928,48 +947,7 @@ # ____________________________________________________________ # Initialization of type objects -def get_parent_layout(w_type): - """Compute the most parent class of 'w_type' whose layout - is the same as 'w_type', or None if all parents of 'w_type' - have a different layout than 'w_type'. - """ - w_starttype = w_type - while len(w_type.bases_w) > 0: - w_bestbase = find_best_base(w_type.space, w_type.bases_w) - if w_type.instancetypedef is not w_bestbase.instancetypedef: - break - if w_type.nslots != w_bestbase.nslots: - break - w_type = w_bestbase - if w_type is not w_starttype: - return w_type - else: - return None - -def issublayout(w_layout1, w_layout2): - space = w_layout2.space - while w_layout1 is not w_layout2: - w_layout1 = find_best_base(space, w_layout1.bases_w) - if w_layout1 is None: - return False - w_layout1 = w_layout1.w_same_layout_as or w_layout1 - return True - -@unroll_safe -def issubtypedef(a, b): - from pypy.objspace.std.objectobject import W_ObjectObject - if b is W_ObjectObject.typedef: - return True - if a is None: - return False - if a is b: - return True - for a1 in a.bases: - if issubtypedef(a1, b): - return True - return False - -def find_best_base(space, bases_w): +def find_best_base(bases_w): """The best base is one of the bases in the given list: the one whose layout a new type should use as a starting point. """ @@ -980,14 +958,10 @@ if w_bestbase is None: w_bestbase = w_candidate # for now continue - candtypedef = w_candidate.instancetypedef - besttypedef = w_bestbase.instancetypedef - if candtypedef is besttypedef: - # two candidates with the same typedef are equivalent unless - # one has extra slots over the other - if w_candidate.nslots > w_bestbase.nslots: - w_bestbase = w_candidate - elif issubtypedef(candtypedef, besttypedef): + cand_layout = w_candidate.layout + best_layout = w_bestbase.layout + if (cand_layout is not best_layout and + cand_layout.issublayout(best_layout)): w_bestbase = w_candidate return w_bestbase @@ -996,20 +970,21 @@ whose layout a new type should use as a starting point. This version checks that bases_w is an acceptable tuple of bases. """ - w_bestbase = find_best_base(space, bases_w) + w_bestbase = find_best_base(bases_w) if w_bestbase is None: raise oefmt(space.w_TypeError, "a new-style class can't have only classic bases") - if not w_bestbase.instancetypedef.acceptable_as_base_class: + if not w_bestbase.layout.typedef.acceptable_as_base_class: raise oefmt(space.w_TypeError, "type '%N' is not an acceptable base class", w_bestbase) - # check that all other bases' layouts are superclasses of the bestbase - w_bestlayout = w_bestbase.w_same_layout_as or w_bestbase + # check that all other bases' layouts are "super-layouts" of the + # bestbase's layout + best_layout = w_bestbase.layout for w_base in bases_w: if isinstance(w_base, W_TypeObject): - w_layout = w_base.w_same_layout_as or w_base - if not issublayout(w_bestlayout, w_layout): + layout = w_base.layout + if not best_layout.issublayout(layout): raise oefmt(space.w_TypeError, "instance layout conflicts in multiple inheritance") return w_bestbase @@ -1023,10 +998,11 @@ w_self.hasdict = w_self.hasdict or w_base.hasdict w_self.needsdel = w_self.needsdel or w_base.needsdel w_self.weakrefable = w_self.weakrefable or w_base.weakrefable - w_self.nslots = w_bestbase.nslots return hasoldstylebase -def create_all_slots(w_self, hasoldstylebase, w_bestbase): +def create_all_slots(w_self, hasoldstylebase, w_bestbase, force_new_layout): + base_layout = w_bestbase.layout + index_next_extra_slot = base_layout.nslots space = w_self.space dict_w = w_self.dict_w if '__slots__' not in dict_w: @@ -1054,7 +1030,8 @@ "__weakref__ slot disallowed: we already got one") wantweakref = True else: - create_slot(w_self, slot_name) + index_next_extra_slot = create_slot(w_self, slot_name, + index_next_extra_slot) wantdict = wantdict or hasoldstylebase if wantdict: create_dict_slot(w_self) @@ -1062,8 +1039,14 @@ create_weakref_slot(w_self) if '__del__' in dict_w: w_self.needsdel = True + # + if index_next_extra_slot == base_layout.nslots and not force_new_layout: + return base_layout + else: + return Layout(base_layout.typedef, index_next_extra_slot, + base_layout=base_layout) -def create_slot(w_self, slot_name): +def create_slot(w_self, slot_name, index_next_extra_slot): space = w_self.space if not valid_slot_name(slot_name): raise oefmt(space.w_TypeError, "__slots__ must be identifiers") @@ -1073,9 +1056,10 @@ # Force interning of slot names. slot_name = space.str_w(space.new_interned_str(slot_name)) # in cpython it is ignored less, but we probably don't care - member = Member(w_self.nslots, slot_name, w_self) + member = Member(index_next_extra_slot, slot_name, w_self) + index_next_extra_slot += 1 w_self.dict_w[slot_name] = space.wrap(member) - w_self.nslots += 1 + return index_next_extra_slot def create_dict_slot(w_self): if not w_self.hasdict: @@ -1097,11 +1081,10 @@ return False return True -def setup_user_defined_type(w_self): +def setup_user_defined_type(w_self, force_new_layout): if len(w_self.bases_w) == 0: w_self.bases_w = [w_self.space.w_object] w_bestbase = check_and_find_best_base(w_self.space, w_self.bases_w) - w_self.instancetypedef = w_bestbase.instancetypedef w_self.flag_heaptype = True for w_base in w_self.bases_w: if not isinstance(w_base, W_TypeObject): @@ -1110,16 +1093,29 @@ w_self.flag_abstract |= w_base.flag_abstract hasoldstylebase = copy_flags_from_bases(w_self, w_bestbase) - create_all_slots(w_self, hasoldstylebase, w_bestbase) + layout = create_all_slots(w_self, hasoldstylebase, w_bestbase, + force_new_layout) ensure_common_attributes(w_self) + return layout -def setup_builtin_type(w_self): - w_self.hasdict = w_self.instancetypedef.hasdict - w_self.weakrefable = w_self.instancetypedef.weakrefable - w_self.w_doc = w_self.space.wrap(w_self.instancetypedef.doc) +def setup_builtin_type(w_self, instancetypedef): + w_self.hasdict = instancetypedef.hasdict + w_self.weakrefable = instancetypedef.weakrefable + w_self.w_doc = w_self.space.wrap(instancetypedef.doc) ensure_common_attributes(w_self) - w_self.flag_heaptype = w_self.instancetypedef.heaptype + w_self.flag_heaptype = instancetypedef.heaptype + # + # usually 'instancetypedef' is new, i.e. not seen in any base, + # but not always (see Exception class) + w_bestbase = find_best_base(w_self.bases_w) + if w_bestbase is None: + parent_layout = None + else: + parent_layout = w_bestbase.layout + if parent_layout.typedef is instancetypedef: + return parent_layout + return Layout(instancetypedef, 0, base_layout=parent_layout) def ensure_common_attributes(w_self): ensure_static_new(w_self) 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 @@ -246,12 +246,12 @@ def _ll_2_int_floordiv_ovf_zer(x, y): if y == 0: raise ZeroDivisionError - if x == -sys.maxint - 1 and y == -1: - raise OverflowError - return llop.int_floordiv(lltype.Signed, x, y) + return _ll_2_int_floordiv_ovf(x, y) def _ll_2_int_floordiv_ovf(x, y): - if x == -sys.maxint - 1 and y == -1: + # intentionally not short-circuited to produce only one guard + # and to remove the check fully if one of the arguments is known + if (x == -sys.maxint - 1) & (y == -1): raise OverflowError return llop.int_floordiv(lltype.Signed, x, y) @@ -263,12 +263,11 @@ def _ll_2_int_mod_ovf_zer(x, y): if y == 0: raise ZeroDivisionError - if x == -sys.maxint - 1 and y == -1: - raise OverflowError - return llop.int_mod(lltype.Signed, x, y) + return _ll_2_int_mod_ovf(x, y) def _ll_2_int_mod_ovf(x, y): - if x == -sys.maxint - 1 and y == -1: + #see comment in _ll_2_int_floordiv_ovf + if (x == -sys.maxint - 1) & (y == -1): raise OverflowError return llop.int_mod(lltype.Signed, x, y) 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 @@ -1199,6 +1199,31 @@ (-sys.maxint-1) // (-6) + 100 * 8) + def test_overflow_fold_if_divisor_constant(self): + import sys + from rpython.rtyper.lltypesystem.lloperation import llop + myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res']) + def f(x, y): + res = 0 + while y > 0: + myjitdriver.can_enter_jit(x=x, y=y, res=res) + myjitdriver.jit_merge_point(x=x, y=y, res=res) + try: + res += llop.int_floordiv_ovf(lltype.Signed, + x, 2) + res += llop.int_mod_ovf(lltype.Signed, + x, 2) + x += 5 + except OverflowError: + res += 100 + y -= 1 + return res + res = self.meta_interp(f, [-41, 8]) + # the guard_true are for the loop condition + # the guard_false needed to check whether an overflow can occur have + # been folded away + self.check_resops(guard_true=2, guard_false=0) + def test_isinstance(self): class A: pass diff --git a/rpython/jit/metainterp/test/test_tlc.py b/rpython/jit/metainterp/test/test_tlc.py --- a/rpython/jit/metainterp/test/test_tlc.py +++ b/rpython/jit/metainterp/test/test_tlc.py @@ -1,5 +1,4 @@ import py -from rpython.rtyper.module.support import LLSupport from rpython.jit.tl import tlc diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -3,7 +3,6 @@ import errno from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT from rpython.rtyper.lltypesystem import lltype, ll2ctypes, rffi -from rpython.rtyper.module.support import StringTraits, UnicodeTraits from rpython.rtyper.tool import rffi_platform from rpython.tool.sourcetools import func_renamer from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -12,7 +11,7 @@ specialize, enforceargs, register_replacement_for, NOT_CONSTANT) from rpython.rlib.signature import signature from rpython.rlib import types -from rpython.annotator.model import s_Str0 +from rpython.annotator.model import s_Str0, s_Unicode0 from rpython.rlib import jit from rpython.translator.platform import platform from rpython.rlib import rstring @@ -342,6 +341,87 @@ rstring.check_str0(res) return res + +class StringTraits: + str = str + str0 = s_Str0 + CHAR = rffi.CHAR + CCHARP = rffi.CCHARP + charp2str = staticmethod(rffi.charp2str) + charpsize2str = staticmethod(rffi.charpsize2str) + scoped_str2charp = staticmethod(rffi.scoped_str2charp) + str2charp = staticmethod(rffi.str2charp) + free_charp = staticmethod(rffi.free_charp) + scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer) + + @staticmethod + def posix_function_name(name): + return UNDERSCORE_ON_WIN32 + name + + @staticmethod + def ll_os_name(name): + return 'll_os.ll_os_' + name + + @staticmethod + @specialize.argtype(0) + def as_str(path): + assert path is not None + if isinstance(path, str): + return path + elif isinstance(path, unicode): + # This never happens in PyPy's Python interpreter! + # Only in raw RPython code that uses unicode strings. + # We implement python2 behavior: silently convert to ascii. + return path.encode('ascii') + else: + return path.as_bytes() + + @staticmethod + @specialize.argtype(0) + def as_str0(path): + res = StringTraits.as_str(path) + rstring.check_str0(res) + return res + + +class UnicodeTraits: + str = unicode + str0 = s_Unicode0 + CHAR = rffi.WCHAR_T + CCHARP = rffi.CWCHARP + charp2str = staticmethod(rffi.wcharp2unicode) + charpsize2str = staticmethod(rffi.wcharpsize2unicode) + str2charp = staticmethod(rffi.unicode2wcharp) + scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp) + free_charp = staticmethod(rffi.free_wcharp) + scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer) + + @staticmethod + def posix_function_name(name): + return UNDERSCORE_ON_WIN32 + 'w' + name + + @staticmethod + @specialize.argtype(0) + def ll_os_name(name): + return 'll_os.ll_os_w' + name + + @staticmethod + @specialize.argtype(0) + def as_str(path): + assert path is not None + if isinstance(path, unicode): + return path + else: + return path.as_unicode() + + @staticmethod + @specialize.argtype(0) + def as_str0(path): + res = UnicodeTraits.as_str(path) + rstring.check_str0(res) + return res + + # Returns True when the unicode function should be called: # - on Windows # - if the path is Unicode. diff --git a/rpython/rlib/rposix_environ.py b/rpython/rlib/rposix_environ.py --- a/rpython/rlib/rposix_environ.py +++ b/rpython/rlib/rposix_environ.py @@ -2,10 +2,10 @@ import sys from rpython.annotator import model as annmodel from rpython.rlib.objectmodel import enforceargs +from rpython.rlib.rposix import _WIN32, StringTraits, UnicodeTraits from rpython.rtyper.controllerentry import Controller from rpython.rtyper.extfunc import register_external from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rtyper.module.support import _WIN32, StringTraits, UnicodeTraits from rpython.translator.tool.cbuild import ExternalCompilationInfo str0 = annmodel.s_Str0 diff --git a/rpython/rtyper/module/test/test_posix.py b/rpython/rlib/test/test_posix.py rename from rpython/rtyper/module/test/test_posix.py rename to rpython/rlib/test/test_posix.py diff --git a/rpython/rlib/test/test_rerased.py b/rpython/rlib/test/test_rerased.py --- a/rpython/rlib/test/test_rerased.py +++ b/rpython/rlib/test/test_rerased.py @@ -192,7 +192,7 @@ def interpret(self, *args, **kwargs): kwargs["taggedpointers"] = True - return BaseRtypingTest.interpret(self, *args, **kwargs) + return BaseRtypingTest.interpret(*args, **kwargs) def test_rtype_1(self): def f(): return eraseX(X()) diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -463,6 +463,9 @@ def remove_regular_struct_content(container): STRUCT = container._TYPE + if isinstance(STRUCT, lltype.FixedSizeArray): + del container._items + return for field_name in STRUCT._names: FIELDTYPE = getattr(STRUCT, field_name) if not isinstance(FIELDTYPE, lltype.ContainerType): @@ -652,6 +655,12 @@ cobj = lltype2ctypes(value) setattr(self._storage.contents, field_name, cobj) + def getitem(self, index, uninitialized_ok=False): + return getattr(self, "item%s" % index) + + def setitem(self, index, value): + setattr(self, "item%s" % index, value) + class _array_mixin(_parentable_mixin): """Mixin added to _array containers when they become ctypes-based.""" __slots__ = () diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -1761,7 +1761,10 @@ def __new__(self, TYPE, n=None, initialization=None, parent=None, parentindex=None): - my_variety = _struct_variety(TYPE._names) + if isinstance(TYPE, FixedSizeArray): + my_variety = _fixedsizearray + else: + my_variety = _struct_variety(TYPE._names) return object.__new__(my_variety) def __init__(self, TYPE, n=None, initialization=None, parent=None, @@ -1771,7 +1774,6 @@ raise TypeError("%r is not variable-sized" % (TYPE,)) if n is None and TYPE._arrayfld is not None: raise TypeError("%r is variable-sized" % (TYPE,)) - first, FIRSTTYPE = TYPE._first_struct() for fld, typ in TYPE._flds.items(): if fld == TYPE._arrayfld: value = _array(typ, n, initialization=initialization, @@ -1814,23 +1816,48 @@ raise UninitializedMemoryAccess("%r.%s"%(self, field_name)) return r - # for FixedSizeArray kind of structs: + +class _fixedsizearray(_struct): + def __init__(self, TYPE, n=None, initialization=None, parent=None, + parentindex=None): + _parentable.__init__(self, TYPE) + if n is not None: + raise TypeError("%r is not variable-sized" % (TYPE,)) + typ = TYPE.OF + storage = [] + for i, fld in enumerate(TYPE._names): + value = typ._allocate(initialization=initialization, + parent=self, parentindex=fld) + storage.append(value) + self._items = storage + if parent is not None: + self._setparentstructure(parent, parentindex) def getlength(self): - assert isinstance(self._TYPE, FixedSizeArray) return self._TYPE.length def getbounds(self): return 0, self.getlength() def getitem(self, index, uninitialized_ok=False): - assert isinstance(self._TYPE, FixedSizeArray) - return self._getattr('item%d' % index, uninitialized_ok) + assert 0 <= index < self.getlength() + return self._items[index] def setitem(self, index, value): - assert isinstance(self._TYPE, FixedSizeArray) - setattr(self, 'item%d' % index, value) + assert 0 <= index < self.getlength() + self._items[index] = value + def __getattr__(self, name): + # obscure + if name.startswith("item"): + return self.getitem(int(name[len('item'):])) + return _struct.__getattr__(self, name) + + def __setattr__(self, name, value): + if name.startswith("item"): + self.setitem(int(name[len('item'):]), value) + return + _struct.__setattr__(self, name, value) class _array(_parentable): _kind = "array" diff --git a/rpython/rtyper/lltypesystem/module/ll_math.py b/rpython/rtyper/lltypesystem/module/ll_math.py --- a/rpython/rtyper/lltypesystem/module/ll_math.py +++ b/rpython/rtyper/lltypesystem/module/ll_math.py @@ -6,8 +6,8 @@ from rpython.translator import cdir from rpython.rlib import jit, rposix from rpython.rlib.rfloat import INFINITY, NAN, isfinite, isinf, isnan +from rpython.rlib.rposix import UNDERSCORE_ON_WIN32 from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.module.support import UNDERSCORE_ON_WIN32 from rpython.tool.sourcetools import func_with_new_name from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.translator.platform import platform diff --git a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py --- a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py @@ -11,12 +11,12 @@ from rpython.rtyper.lltypesystem.ll2ctypes import _llgcopaque from rpython.rtyper.annlowlevel import llhelper from rpython.rlib import rposix +from rpython.rlib.rposix import UNDERSCORE_ON_WIN32 from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.translator import cdir from rpython.tool.udir import udir from rpython.rtyper.test.test_llinterp import interpret from rpython.annotator.annrpython import RPythonAnnotator -from rpython.rtyper.module.support import UNDERSCORE_ON_WIN32 from rpython.rtyper.rtyper import RPythonTyper from rpython.rlib.rarithmetic import r_uint, get_long_pattern, is_emulated_long from rpython.rlib.rarithmetic import is_valid_int diff --git a/rpython/rtyper/module/__init__.py b/rpython/rtyper/module/__init__.py deleted file mode 100644 --- a/rpython/rtyper/module/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/rpython/rtyper/module/support.py b/rpython/rtyper/module/support.py deleted file mode 100644 --- a/rpython/rtyper/module/support.py +++ /dev/null @@ -1,139 +0,0 @@ -import sys - -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import specialize -from rpython.rlib import rstring - -_WIN32 = sys.platform.startswith('win') -UNDERSCORE_ON_WIN32 = '_' if _WIN32 else '' - -# utility conversion functions -class LLSupport: - _mixin_ = True - - def to_rstr(s): - from rpython.rtyper.lltypesystem.rstr import STR, mallocstr - if s is None: - return lltype.nullptr(STR) - p = mallocstr(len(s)) - for i in range(len(s)): - p.chars[i] = s[i] - return p - to_rstr = staticmethod(to_rstr) - - def to_runicode(s): - from rpython.rtyper.lltypesystem.rstr import UNICODE, mallocunicode - if s is None: - return lltype.nullptr(UNICODE) - p = mallocunicode(len(s)) - for i in range(len(s)): - p.chars[i] = s[i] - return p - to_runicode = staticmethod(to_runicode) - - def from_rstr(rs): - if not rs: # null pointer - return None - else: - return ''.join([rs.chars[i] for i in range(len(rs.chars))]) - from_rstr = staticmethod(from_rstr) - - def from_rstr_nonnull(rs): - assert rs - return ''.join([rs.chars[i] for i in range(len(rs.chars))]) - from_rstr_nonnull = staticmethod(from_rstr_nonnull) - - -class StringTraits: - str = str - str0 = annmodel.s_Str0 - CHAR = rffi.CHAR - CCHARP = rffi.CCHARP - charp2str = staticmethod(rffi.charp2str) - charpsize2str = staticmethod(rffi.charpsize2str) - scoped_str2charp = staticmethod(rffi.scoped_str2charp) - str2charp = staticmethod(rffi.str2charp) - free_charp = staticmethod(rffi.free_charp) - scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer) - - @staticmethod - def posix_function_name(name): - return UNDERSCORE_ON_WIN32 + name - - @staticmethod - def ll_os_name(name): - return 'll_os.ll_os_' + name - - @staticmethod - @specialize.argtype(0) - def as_str(path): - assert path is not None - if isinstance(path, str): - return path - elif isinstance(path, unicode): - # This never happens in PyPy's Python interpreter! - # Only in raw RPython code that uses unicode strings. - # We implement python2 behavior: silently convert to ascii. - return path.encode('ascii') - else: - return path.as_bytes() - - @staticmethod - @specialize.argtype(0) - def as_str0(path): - res = StringTraits.as_str(path) - rstring.check_str0(res) - return res - -class UnicodeTraits: - str = unicode - str0 = annmodel.s_Unicode0 - CHAR = rffi.WCHAR_T - CCHARP = rffi.CWCHARP - charp2str = staticmethod(rffi.wcharp2unicode) - charpsize2str = staticmethod(rffi.wcharpsize2unicode) - str2charp = staticmethod(rffi.unicode2wcharp) - scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp) - free_charp = staticmethod(rffi.free_wcharp) - scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer) - - @staticmethod - def posix_function_name(name): - return UNDERSCORE_ON_WIN32 + 'w' + name - - @staticmethod - @specialize.argtype(0) - def ll_os_name(name): - return 'll_os.ll_os_w' + name - - @staticmethod - @specialize.argtype(0) - def as_str(path): - assert path is not None - if isinstance(path, unicode): - return path - else: - return path.as_unicode() - - @staticmethod - @specialize.argtype(0) - def as_str0(path): - res = UnicodeTraits.as_str(path) - rstring.check_str0(res) - return res - -def ll_strcpy(dst_s, src_s, n): - dstchars = dst_s.chars - srcchars = src_s.chars - i = 0 - while i < n: - dstchars[i] = srcchars[i] - i += 1 - -def _ll_strfill(dst_s, srcchars, n): - dstchars = dst_s.chars - i = 0 - while i < n: - dstchars[i] = srcchars[i] - i += 1 diff --git a/rpython/rtyper/module/test/__init__.py b/rpython/rtyper/module/test/__init__.py deleted file mode 100644 --- a/rpython/rtyper/module/test/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/rpython/rtyper/module/test/test_ll_strtod.py b/rpython/rtyper/module/test/test_ll_strtod.py deleted file mode 100644 --- a/rpython/rtyper/module/test/test_ll_strtod.py +++ /dev/null @@ -1,13 +0,0 @@ -import py - -from rpython.rtyper.test.tool import BaseRtypingTest -from rpython.rlib import rfloat - -class TestStrtod(BaseRtypingTest): - def test_formatd(self): - for flags in [0, - rfloat.DTSF_ADD_DOT_0]: - def f(y): - return rfloat.formatd(y, 'g', 2, flags) - - assert self.ll_to_string(self.interpret(f, [3.0])) == f(3.0) diff --git a/rpython/rtyper/test/test_rfloat.py b/rpython/rtyper/test/test_rfloat.py --- a/rpython/rtyper/test/test_rfloat.py +++ b/rpython/rtyper/test/test_rfloat.py @@ -204,6 +204,14 @@ res = self.ll_to_string(self.interpret(f, [10/3.0])) assert res == '3.33' + def test_formatd_g(self): + from rpython.rlib import rfloat + for flags in [0, rfloat.DTSF_ADD_DOT_0]: + def f(y): + return rfloat.formatd(y, 'g', 2, flags) + + assert self.ll_to_string(self.interpret(f, [3.0])) == f(3.0) + def test_formatd_repr(self): from rpython.rlib.rfloat import formatd def f(x): diff --git a/rpython/rtyper/test/test_rpbc.py b/rpython/rtyper/test/test_rpbc.py --- a/rpython/rtyper/test/test_rpbc.py +++ b/rpython/rtyper/test/test_rpbc.py @@ -1945,7 +1945,7 @@ def interpret(self, fn, args, **kwds): kwds['config'] = self.config - return TestRPBC.interpret(self, fn, args, **kwds) + return TestRPBC.interpret(fn, args, **kwds) def test_smallfuncsets_basic(): from rpython.translator.translator import TranslationContext, graphof diff --git a/rpython/rtyper/test/tool.py b/rpython/rtyper/test/tool.py --- a/rpython/rtyper/test/tool.py +++ b/rpython/rtyper/test/tool.py @@ -5,22 +5,27 @@ class BaseRtypingTest(object): FLOAT_PRECISION = 8 - def gengraph(self, func, argtypes=[], viewbefore='auto', policy=None, + @staticmethod + def gengraph(func, argtypes=[], viewbefore='auto', policy=None, backendopt=False, config=None): return gengraph(func, argtypes, viewbefore, policy, backendopt=backendopt, config=config) - def interpret(self, fn, args, **kwds): + @staticmethod + def interpret(fn, args, **kwds): return interpret(fn, args, **kwds) - def interpret_raises(self, exc, fn, args, **kwds): + @staticmethod + def interpret_raises(exc, fn, args, **kwds): return interpret_raises(exc, fn, args, **kwds) - def float_eq(self, x, y): + @staticmethod + def float_eq(x, y): return x == y - def float_eq_approx(self, x, y): - maxError = 10**-self.FLOAT_PRECISION + @classmethod + def float_eq_approx(cls, x, y): + maxError = 10**-cls.FLOAT_PRECISION if abs(x-y) < maxError: return True @@ -31,45 +36,66 @@ return relativeError < maxError - def is_of_type(self, x, type_): + @staticmethod + def is_of_type(x, type_): return type(x) is type_ - def _skip_llinterpreter(self, reason): + @staticmethod + def _skip_llinterpreter(reason): py.test.skip("lltypesystem doesn't support %s, yet" % reason) - def ll_to_string(self, s): + @staticmethod + def ll_to_string(s): if not s: return None return ''.join(s.chars) - def ll_to_unicode(self, s): + @staticmethod + def ll_to_unicode(s): return u''.join(s.chars) - def string_to_ll(self, s): - from rpython.rtyper.module.support import LLSupport - return LLSupport.to_rstr(s) + @staticmethod + def string_to_ll(s): + from rpython.rtyper.lltypesystem.rstr import STR, mallocstr + if s is None: + return lltype.nullptr(STR) + p = mallocstr(len(s)) + for i in range(len(s)): + p.chars[i] = s[i] + return p - def unicode_to_ll(self, s): - from rpython.rtyper.module.support import LLSupport - return LLSupport.to_runicode(s) + @staticmethod + def unicode_to_ll(s): + from rpython.rtyper.lltypesystem.rstr import UNICODE, mallocunicode + if s is None: + return lltype.nullptr(UNICODE) + p = mallocunicode(len(s)) + for i in range(len(s)): + p.chars[i] = s[i] + return p - def ll_to_list(self, l): + @staticmethod + def ll_to_list(l): r = [] items = l.ll_items() for i in range(l.ll_length()): r.append(items[i]) return r - def ll_unpack_tuple(self, t, length): + @staticmethod + def ll_unpack_tuple(t, length): return tuple([getattr(t, 'item%d' % i) for i in range(length)]) - def get_callable(self, fnptr): + @staticmethod + def get_callable(fnptr): return fnptr._obj._callable - def class_name(self, value): + @staticmethod + def class_name(value): return ''.join(value.super.typeptr.name.chars) - def read_attr(self, value, attr_name): + @staticmethod + def read_attr(value, attr_name): value = value._obj while value is not None: attr = getattr(value, "inst_" + attr_name, None) @@ -79,6 +105,7 @@ return attr raise AttributeError() - def is_of_instance_type(self, val): + @staticmethod + def is_of_instance_type(val): T = lltype.typeOf(val) return isinstance(T, lltype.Ptr) and isinstance(T.TO, lltype.GcStruct) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit