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

Reply via email to