Author: Ronan Lamy <[email protected]>
Branch: var-in-Some
Changeset: r73867:77ca6f4b2c85
Date: 2014-10-09 19:20 +0100
http://bitbucket.org/pypy/pypy/changeset/77ca6f4b2c85/

Log:    hg merge default

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -12,3 +12,6 @@
 Allocate by 4-byte chunks in rffi_platform,
 Skip testing objdump if it does not exist,
 and other small adjustments in own tests
+
+.. branch: rtyper-stuff
+Small internal refactorings in the rtyper.
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -37,6 +37,13 @@
 using a 32 bit Python and vice versa. By default pypy is built using the 
 Multi-threaded DLL (/MD) runtime environment.
 
+If you wish to override this detection method to use a different compiler
+(mingw or a different version of MSVC):
+
+* set up the PATH and other environment variables as needed
+* set the `CC` environment variable to compiler exe to be used,
+  for a different version of MSVC `SET CC=cl.exe`.
+
 **Note:** PyPy is currently not supported for 64 bit Python, and translation
 will fail in this case.
 
@@ -264,7 +271,7 @@
 Since hacking on PyPy means running tests, you will need a way to specify
 the mingw compiler when hacking (as opposed to translating). As of
 March 2012, --cc is not a valid option for pytest.py. However if you set an
-environment variable CC to the compliter exe, testing will use it.
+environment variable CC to the compiler exe, testing will use it.
 
 .. _`mingw32 build`: 
http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
 .. _`mingw64 build`: 
http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds
diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py
--- a/pypy/module/_socket/__init__.py
+++ b/pypy/module/_socket/__init__.py
@@ -17,8 +17,6 @@
     def startup(self, space):
         from rpython.rlib.rsocket import rsocket_startup
         rsocket_startup()
-        from pypy.module._socket.interp_func import State
-        space.fromcache(State).startup(space)
 
     def buildloaders(cls):
         from rpython.rlib import rsocket
diff --git a/pypy/module/_socket/interp_func.py 
b/pypy/module/_socket/interp_func.py
--- a/pypy/module/_socket/interp_func.py
+++ b/pypy/module/_socket/interp_func.py
@@ -1,5 +1,6 @@
 from rpython.rlib import rsocket
 from rpython.rlib.rsocket import SocketError, INVALID_SOCKET
+from rpython.rlib.rarithmetic import intmask
 
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
@@ -46,9 +47,8 @@
     Return the true host name, a list of aliases, and a list of IP addresses,
     for a host.  The host argument is a string giving a host name or IP number.
     """
-    lock = space.fromcache(State).netdb_lock
     try:
-        res = rsocket.gethostbyname_ex(host, lock)
+        res = rsocket.gethostbyname_ex(host)
     except SocketError, e:
         raise converted_error(space, e)
     return common_wrapgethost(space, res)
@@ -60,9 +60,8 @@
     Return the true host name, a list of aliases, and a list of IP addresses,
     for a host.  The host argument is a string giving a host name or IP number.
     """
-    lock = space.fromcache(State).netdb_lock
     try:
-        res = rsocket.gethostbyaddr(host, lock)
+        res = rsocket.gethostbyaddr(host)
     except SocketError, e:
         raise converted_error(space, e)
     return common_wrapgethost(space, res)
@@ -174,7 +173,7 @@
 
     Convert a 16-bit integer from network to host byte order.
     """
-    return space.wrap(rsocket.ntohs(x))
+    return space.wrap(rsocket.ntohs(intmask(x)))
 
 @unwrap_spec(x="c_uint")
 def ntohl(space, x):
@@ -190,7 +189,7 @@
 
     Convert a 16-bit integer from host to network byte order.
     """
-    return space.wrap(rsocket.htons(x))
+    return space.wrap(rsocket.htons(intmask(x)))
 
 @unwrap_spec(x="c_uint")
 def htonl(space, x):
@@ -319,10 +318,3 @@
             raise OperationError(space.w_ValueError,
                                  space.wrap('Timeout value out of range'))
     rsocket.setdefaulttimeout(timeout)
-
-class State(object):
-    def __init__(self, space):
-        self.netdb_lock = None
-
-    def startup(self, space):
-        self.netdb_lock = space.allocate_lock()
diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -109,10 +109,11 @@
 
 # XXX Hack to seperate rpython and pypy
 def make_ushort_port(space, port):
+    assert isinstance(port, int)
     if port < 0 or port > 0xffff:
         raise OperationError(space.w_OverflowError, space.wrap(
             "port must be 0-65535."))
-    return rffi.cast(rffi.USHORT, port)
+    return port
 
 def make_unsigned_flowinfo(space, flowinfo):
     if flowinfo < 0 or flowinfo > 0xfffff:
@@ -401,8 +402,10 @@
         The value argument can either be an integer or a string.
         """
         try:
-            optval = space.int_w(w_optval)
-        except:
+            optval = space.c_int_w(w_optval)
+        except OperationError, e:
+            if e.async(space):
+                raise
             optval = space.str_w(w_optval)
             try:
                 self.sock.setsockopt(level, optname, optval)
diff --git a/pypy/module/_socket/test/test_sock_app.py 
b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -498,6 +498,13 @@
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
         assert reuse == 0
+        #
+        raises(TypeError, s.setsockopt, socket.SOL_SOCKET,
+                          socket.SO_REUSEADDR, 2 ** 31)
+        raises(TypeError, s.setsockopt, socket.SOL_SOCKET,
+                          socket.SO_REUSEADDR, 2 ** 32 + 1)
+        assert s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 0
+        #
         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
         assert reuse != 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
@@ -116,6 +116,8 @@
     validate_fd(fileno(fp))
     return _feof(fp)
 
+def is_valid_fp(fp):
+    return is_valid_fd(fileno(fp))
 
 constant_names = """
 Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -3,7 +3,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (
     cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP,
-    cpython_struct)
+    cpython_struct, is_valid_fp)
 from pypy.module.cpyext.pyobject import PyObject, borrow_from
 from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno
 from pypy.module.cpyext.funcobject import PyCodeObject
@@ -154,6 +154,10 @@
     source = ""
     filename = rffi.charp2str(filename)
     buf = lltype.malloc(rffi.CCHARP.TO, BUF_SIZE, flavor='raw')
+    if not is_valid_fp(fp):
+        lltype.free(buf, flavor='raw')
+        PyErr_SetFromErrno(space, space.w_IOError)
+        return None
     try:
         while True:
             count = fread(buf, 1, BUF_SIZE, fp)
diff --git a/pypy/module/cpyext/test/test_eval.py 
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -89,12 +89,12 @@
                 rffi.free_charp(buf)
 
         assert 0 == run("42 * 43")
-        
+
         assert -1 == run("4..3 * 43")
-        
+
         assert api.PyErr_Occurred()
         api.PyErr_Clear()
-        
+
     def test_run_string(self, space, api):
         def run(code, start, w_globals, w_locals):
             buf = rffi.str2charp(code)
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -3,7 +3,7 @@
 from rpython.rlib.buffer import SubBuffer
 from rpython.rlib.rstring import strip_spaces
 from rpython.rtyper.lltypesystem import lltype, rffi
-from pypy.module.micronumpy import descriptor, loop
+from pypy.module.micronumpy import descriptor, loop, support
 from pypy.module.micronumpy.base import (
     W_NDimArray, convert_to_array, W_NumpyObject)
 from pypy.module.micronumpy.converters import shape_converter
@@ -134,6 +134,15 @@
     if dtype.is_str_or_unicode() and dtype.elsize < 1:
         dtype = descriptor.variable_dtype(space, dtype.char + '1')
     shape = shape_converter(space, w_shape, dtype)
+    for dim in shape:
+        if dim < 0:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "negative dimensions are not allowed"))
+    try:
+        support.product(shape)
+    except OverflowError:
+        raise OperationError(space.w_ValueError, space.wrap(
+            "array is too big."))
     return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero)
 
 def empty(space, w_shape, w_dtype=None, w_order=None):
diff --git a/pypy/module/micronumpy/support.py 
b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -1,5 +1,6 @@
 from pypy.interpreter.error import OperationError, oefmt
 from rpython.rlib import jit
+from rpython.rlib.rarithmetic import ovfcheck
 
 
 def issequence_w(space, w_obj):
@@ -23,7 +24,7 @@
 def product(s):
     i = 1
     for x in s:
-        i *= x
+        i = ovfcheck(i * x)
     return i
 
 
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
@@ -384,6 +384,19 @@
         assert zeros((), dtype='S').shape == ()
         assert zeros((), dtype='S').dtype == '|S1'
 
+    def test_check_shape(self):
+        import numpy as np
+        for func in [np.zeros, np.empty]:
+            exc = raises(ValueError, func, [0, -1, 1], 'int8')
+            assert str(exc.value) == "negative dimensions are not allowed"
+            exc = raises(ValueError, func, [2, -1, 3], 'int8')
+            assert str(exc.value) == "negative dimensions are not allowed"
+
+            exc = raises(ValueError, func, [975]*7, 'int8')
+            assert str(exc.value) == "array is too big."
+            exc = raises(ValueError, func, [26244]*5, 'int8')
+            assert str(exc.value) == "array is too big."
+
     def test_empty_like(self):
         import numpy as np
         a = np.empty_like(np.zeros(()))
diff --git a/pypy/module/micronumpy/test/test_zjit.py 
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -599,8 +599,7 @@
             'float_mul': 2,
             'getarrayitem_gc': 7,
             'getarrayitem_gc_pure': 15,
-            'getfield_gc': 8,
-            'getfield_gc_pure': 44,
+            'getfield_gc_pure': 52,
             'guard_class': 4,
             'guard_false': 14,
             'guard_not_invalidated': 2,
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py 
b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -85,9 +85,9 @@
             p38 = call(ConstClass(_ll_0_threadlocalref_getter___), 
descr=<Callr . EF=1 OS=5>)
             p39 = getfield_gc(p38, descr=<FieldP 
pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
             i40 = force_token()
-            p41 = getfield_gc(p38, descr=<FieldP 
pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
+            p41 = getfield_gc_pure(p38, descr=<FieldP 
pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
             guard_value(p41, ConstPtr(ptr42), descr=...)
-            i42 = getfield_gc(p38, descr=<FieldU 
pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
+            i42 = getfield_gc_pure(p38, descr=<FieldU 
pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
             i43 = int_is_zero(i42)
             guard_true(i43, descr=...)
             i50 = force_token()
@@ -447,9 +447,9 @@
             p29 = call(ConstClass(_ll_0_threadlocalref_getter___), 
descr=<Callr . EF=1 OS=5>)
             p30 = getfield_gc(p29, descr=<FieldP 
pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
             p31 = force_token()
-            p32 = getfield_gc(p29, descr=<FieldP 
pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
+            p32 = getfield_gc_pure(p29, descr=<FieldP 
pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
             guard_value(p32, ConstPtr(ptr33), descr=...)
-            i34 = getfield_gc(p29, descr=<FieldU 
pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
+            i34 = getfield_gc_pure(p29, descr=<FieldU 
pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
             i35 = int_is_zero(i34)
             guard_true(i35, descr=...)
             p37 = getfield_gc(ConstPtr(ptr36), descr=<FieldP 
pypy.interpreter.nestedscope.Cell.inst_w_value .*>)
diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -785,6 +785,7 @@
             raise Exception("getfield_raw_r (without _pure) not supported")
         #
         if immut in (IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY):
+            op1.opname += "_pure"
             descr1 = self.cpu.fielddescrof(
                 v_inst.concretetype.TO,
                 quasiimmut.get_mutate_field_name(c_fieldname.value))
diff --git a/rpython/jit/codewriter/test/test_jtransform.py 
b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -1296,7 +1296,7 @@
         assert op1.args[1] == ('fielddescr', STRUCT, 'inst_x')
         assert op1.args[2] == ('fielddescr', STRUCT, 'mutate_x')
         assert op1.result is None
-        assert op2.opname == 'getfield_gc_i'
+        assert op2.opname == 'getfield_gc_i_pure'
         assert len(op2.args) == 2
         assert op2.args[0] == v_x
         assert op2.args[1] == ('fielddescr', STRUCT, 'inst_x')
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py 
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -6,6 +6,7 @@
 from rpython.jit.metainterp.jitexc import JitException
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, 
MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
+from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.rlib.objectmodel import we_are_translated
 
@@ -531,10 +532,14 @@
 
     def optimize_QUASIIMMUT_FIELD(self, op):
         # Pattern: QUASIIMMUT_FIELD(s, descr=QuasiImmutDescr)
-        #          x = GETFIELD_GC(s, descr='inst_x')
-        # If 's' is a constant (after optimizations), then we make 's.inst_x'
-        # a constant too, and we rely on the rest of the optimizations to
-        # constant-fold the following getfield_gc.
+        #          x = GETFIELD_GC_PURE(s, descr='inst_x')
+        # If 's' is a constant (after optimizations) we rely on the rest of the
+        # optimizations to constant-fold the following getfield_gc_pure.
+        # in addition, we record the dependency here to make invalidation work
+        # correctly.
+        # NB: emitting the GETFIELD_GC_PURE is only safe because the
+        # QUASIIMMUT_FIELD is also emitted to make sure the dependency is
+        # registered.
         structvalue = self.getvalue(op.getarg(0))
         if not structvalue.is_constant():
             self._remove_guard_not_invalidated = True
@@ -544,21 +549,14 @@
         qmutdescr = op.getdescr()
         assert isinstance(qmutdescr, QuasiImmutDescr)
         # check that the value is still correct; it could have changed
-        # already between the tracing and now.  In this case, we are
-        # simply ignoring the QUASIIMMUT_FIELD hint and compiling it
-        # as a regular getfield.
+        # already between the tracing and now.  In this case, we mark the loop
+        # as invalid
         if not qmutdescr.is_still_valid_for(structvalue.get_key_box()):
-            self._remove_guard_not_invalidated = True
-            return
+            raise InvalidLoop('quasi immutable field changed during tracing')
         # record as an out-of-line guard
         if self.optimizer.quasi_immutable_deps is None:
             self.optimizer.quasi_immutable_deps = {}
         self.optimizer.quasi_immutable_deps[qmutdescr.qmut] = None
-        # perform the replacement in the list of operations
-        fieldvalue = self.getvalue(qmutdescr.constantfieldbox)
-        cf = self.field_cache(qmutdescr.fielddescr)
-        cf.force_lazy_setfield(self)
-        cf.remember_field_value(structvalue, fieldvalue)
         self._remove_guard_not_invalidated = False
 
     def optimize_GUARD_NOT_INVALIDATED(self, op):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -5200,7 +5200,7 @@
         []
         quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i0 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
+        i0 = getfield_gc_pure(ConstPtr(quasiptr), descr=quasifielddescr)
         i1 = call_pure(123, i0, descr=nonwritedescr)
         finish(i1)
         """
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -6893,13 +6893,13 @@
         [p0, p1, i0]
         quasiimmut_field(p0, descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i1 = getfield_gc(p0, descr=quasifielddescr)
+        i1 = getfield_gc_pure(p0, descr=quasifielddescr)
         escape(i1)
         jump(p1, p0, i1)
         """
         expected = """
         [p0, p1, i0]
-        i1 = getfield_gc(p0, descr=quasifielddescr)
+        i1 = getfield_gc_pure(p0, descr=quasifielddescr)
         escape(i1)
         jump(p1, p0, i1)
         """
@@ -6910,7 +6910,7 @@
         []
         quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i1 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
+        i1 = getfield_gc_pure(ConstPtr(quasiptr), descr=quasifielddescr)
         escape(i1)
         jump()
         """
@@ -6962,11 +6962,11 @@
         [i0a, i0b]
         quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i1 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
+        i1 = getfield_gc_pure(ConstPtr(quasiptr), descr=quasifielddescr)
         call_may_force(i0b, descr=mayforcevirtdescr)
         quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i2 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
+        i2 = getfield_gc_pure(ConstPtr(quasiptr), descr=quasifielddescr)
         i3 = escape(i1)
         i4 = escape(i2)
         jump(i3, i4)
@@ -6989,11 +6989,11 @@
         setfield_gc(p, 421, descr=quasifielddescr)
         quasiimmut_field(p, descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i1 = getfield_gc(p, descr=quasifielddescr)
+        i1 = getfield_gc_pure(p, descr=quasifielddescr)
         call_may_force(i0b, descr=mayforcevirtdescr)
         quasiimmut_field(p, descr=quasiimmutdescr)
         guard_not_invalidated() []
-        i2 = getfield_gc(p, descr=quasifielddescr)
+        i2 = getfield_gc_pure(p, descr=quasifielddescr)
         i3 = escape(i1)
         i4 = escape(i2)
         jump(i3, i4)
@@ -8242,7 +8242,7 @@
 
         quasiimmut_field(p69, descr=quasiimmutdescr)
         guard_not_invalidated() []
-        p71 = getfield_gc(p69, descr=quasifielddescr) # inst_code
+        p71 = getfield_gc_pure(p69, descr=quasifielddescr) # inst_code
         guard_value(p71, -4247) []
 
         p106 = new_with_vtable(ConstClass(node_vtable))
@@ -8253,30 +8253,18 @@
         setfield_gc(p106, p108, descr=nextdescr) # inst_storage
         jump(p106)
         """
-        expected = """
-        []
-        p72 = getfield_gc(ConstPtr(myptr2), descr=quasifielddescr)
-        guard_value(p72, -4247) []
-        jump()
-        """
-        self.optimize_loop(ops, expected)
+        self.raises(InvalidLoop, self.optimize_loop, ops, ops)
 
     def test_issue1080_infinitie_loop_simple(self):
         ops = """
         [p69]
         quasiimmut_field(p69, descr=quasiimmutdescr)
         guard_not_invalidated() []
-        p71 = getfield_gc(p69, descr=quasifielddescr) # inst_code
+        p71 = getfield_gc_pure(p69, descr=quasifielddescr) # inst_code
         guard_value(p71, -4247) []
         jump(ConstPtr(myptr))
         """
-        expected = """
-        []
-        p72 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
-        guard_value(p72, -4247) []
-        jump()
-        """
-        self.optimize_loop(ops, expected)
+        self.raises(InvalidLoop, self.optimize_loop, ops, ops)
 
     def test_only_strengthen_guard_if_class_matches(self):
         ops = """
diff --git a/rpython/jit/metainterp/test/test_quasiimmut.py 
b/rpython/jit/metainterp/test/test_quasiimmut.py
--- a/rpython/jit/metainterp/test/test_quasiimmut.py
+++ b/rpython/jit/metainterp/test/test_quasiimmut.py
@@ -81,6 +81,27 @@
             assert len(loop.quasi_immutable_deps) == 1
             assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
 
+    def test_simple_optimize_during_tracing(self):
+        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
+        class Foo:
+            _immutable_fields_ = ['a?']
+            def __init__(self, a):
+                self.a = a
+        def f(a, x):
+            foo = Foo(a)
+            total = 0
+            while x > 0:
+                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
+                # read a quasi-immutable field out of a Constant
+                total += foo.a
+                x -= 1
+            return total
+        #
+        res = self.meta_interp(f, [100, 7], enable_opts="")
+        assert res == 700
+        # there should be no getfields, even though optimizations are turned 
off
+        self.check_resops(guard_not_invalidated=1, getfield_gc=0)
+
     def test_nonopt_1(self):
         myjitdriver = JitDriver(greens=[], reds=['x', 'total', 'lst'])
         class Foo:
@@ -102,7 +123,7 @@
         assert f(100, 7) == 721
         res = self.meta_interp(f, [100, 7])
         assert res == 721
-        self.check_resops(guard_not_invalidated=0, getfield_gc=3)
+        self.check_resops(guard_not_invalidated=0, getfield_gc=1, 
getfield_gc_pure=2)
         #
         from rpython.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -154,11 +175,12 @@
                 residual_call(foo)
                 x -= 1
             return total
-        #
+
         assert f(100, 7) == 721
         res = self.meta_interp(f, [100, 7])
         assert res == 721
-        self.check_resops(guard_not_invalidated=0, getfield_gc=2)
+        # the loop is invalid, so nothing is traced
+        self.check_aborted_count(2)
 
     def test_change_during_tracing_2(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -184,7 +206,7 @@
         assert f(100, 7) == 700
         res = self.meta_interp(f, [100, 7])
         assert res == 700
-        self.check_resops(guard_not_invalidated=0, getfield_gc=2)
+        self.check_resops(guard_not_invalidated=0, getfield_gc=0)
 
     def test_change_invalidate_reentering(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -347,7 +369,7 @@
         res = self.meta_interp(f, [100, 7])
         assert res == 700
         self.check_resops(getarrayitem_gc_pure=0, guard_not_invalidated=2,
-                          getarrayitem_gc=0, getfield_gc=0)
+                          getarrayitem_gc=0, getfield_gc=0, getfield_gc_pure=0)
         #
         from rpython.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -355,6 +377,30 @@
             assert len(loop.quasi_immutable_deps) == 1
             assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
 
+    def test_list_optimized_while_tracing(self):
+        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
+        class Foo:
+            _immutable_fields_ = ['lst?[*]']
+            def __init__(self, lst):
+                self.lst = lst
+        def f(a, x):
+            lst1 = [0, 0]
+            lst1[1] = a
+            foo = Foo(lst1)
+            total = 0
+            while x > 0:
+                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
+                # read a quasi-immutable field out of a Constant
+                total += foo.lst[1]
+                x -= 1
+            return total
+        #
+        res = self.meta_interp(f, [100, 7], enable_opts="")
+        assert res == 700
+        # operations must have been removed by the frontend
+        self.check_resops(getarrayitem_gc_pure=0, guard_not_invalidated=1,
+                          getarrayitem_gc=0, getfield_gc=0, getfield_gc_pure=0)
+
     def test_list_length_1(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
         class Foo:
diff --git a/rpython/rlib/_stacklet_n_a.py b/rpython/rlib/_stacklet_n_a.py
--- a/rpython/rlib/_stacklet_n_a.py
+++ b/rpython/rlib/_stacklet_n_a.py
@@ -1,33 +1,35 @@
 from rpython.rlib import _rffi_stacklet as _c
-from rpython.rlib import objectmodel, debug
+from rpython.rlib import debug
+from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.rtyper.annlowlevel import llhelper
-from rpython.tool.staticmethods import StaticMethods
 
 
-class StackletGcRootFinder:
-    __metaclass__ = StaticMethods
-
+class StackletGcRootFinder(object):
+    @staticmethod
+    @specialize.arg(1)
     def new(thrd, callback, arg):
         h = _c.new(thrd._thrd, llhelper(_c.run_fn, callback), arg)
         if not h:
             raise MemoryError
         return h
-    new._annspecialcase_ = 'specialize:arg(1)'
 
+    @staticmethod
     def switch(h):
         h = _c.switch(h)
         if not h:
             raise MemoryError
         return h
 
+    @staticmethod
     def destroy(thrd, h):
         _c.destroy(thrd._thrd, h)
-        if objectmodel.we_are_translated():
+        if we_are_translated():
             debug.debug_print("not using a framework GC: "
                               "stacklet_destroy() may leak")
 
-    is_empty_handle = _c.is_empty_handle
+    is_empty_handle = staticmethod(_c.is_empty_handle)
 
+    @staticmethod
     def get_null_handle():
         return _c.null_handle
 
diff --git a/rpython/rlib/_stacklet_shadowstack.py 
b/rpython/rlib/_stacklet_shadowstack.py
--- a/rpython/rlib/_stacklet_shadowstack.py
+++ b/rpython/rlib/_stacklet_shadowstack.py
@@ -3,7 +3,6 @@
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.tool.staticmethods import StaticMethods
 
 
 NULL_SUSPSTACK = lltype.nullptr(llmemory.GCREF.TO)
@@ -68,9 +67,7 @@
     return oldsuspstack
 
 
-class StackletGcRootFinder:
-    __metaclass__ = StaticMethods
-
+class StackletGcRootFinder(object):
     def new(thrd, callback, arg):
         gcrootfinder.callback = callback
         thread_handle = thrd._thrd
@@ -78,6 +75,7 @@
         h = _c.new(thread_handle, llhelper(_c.run_fn, _new_callback), arg)
         return get_result_suspstack(h)
     new._dont_inline_ = True
+    new = staticmethod(new)
 
     def switch(suspstack):
         # suspstack has a handle to target, i.e. where to switch to
@@ -90,10 +88,13 @@
         h = _c.switch(h)
         return get_result_suspstack(h)
     switch._dont_inline_ = True
+    switch = staticmethod(switch)
 
+    @staticmethod
     def is_empty_handle(suspstack):
         return not suspstack
 
+    @staticmethod
     def get_null_handle():
         return NULL_SUSPSTACK
 
diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -134,8 +134,8 @@
 
 if _CYGWIN:
     # XXX: macro=True hack for newer versions of Cygwin (as of 12/2012)
-    c_malloc, _ = external('malloc', [size_t], PTR, macro=True)
-    c_free, _ = external('free', [PTR], lltype.Void, macro=True)
+    _, c_malloc_safe = external('malloc', [size_t], PTR, macro=True)
+    _, c_free_safe = external('free', [PTR], lltype.Void, macro=True)
 
 c_memmove, _ = external('memmove', [PTR, PTR, size_t], lltype.Void)
 
@@ -709,7 +709,7 @@
             # XXX: JIT memory should be using mmap MAP_PRIVATE with
             #      PROT_EXEC but Cygwin's fork() fails.  mprotect()
             #      cannot be used, but seems to be unnecessary there.
-            res = c_malloc(map_size)
+            res = c_malloc_safe(map_size)
             if res == rffi.cast(PTR, 0):
                 raise MemoryError
             return res
@@ -726,7 +726,7 @@
     alloc._annenforceargs_ = (int,)
 
     if _CYGWIN:
-        free = c_free
+        free = c_free_safe
     else:
         free = c_munmap_safe
 
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -18,9 +18,10 @@
 from rpython.rlib import _rsocket_rffi as _c, jit, rgc
 from rpython.rlib.objectmodel import instantiate, keepalive_until_here
 from rpython.rlib.rarithmetic import intmask, r_uint
-from rpython.rlib.rthread import dummy_lock
+from rpython.rlib import rthread
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper.lltypesystem.rffi import sizeof, offsetof
+from rpython.rtyper.extregistry import ExtRegistryEntry
 
 
 # Usage of @jit.dont_look_inside in this file is possibly temporary
@@ -51,6 +52,7 @@
 
 
 def ntohs(x):
+    assert isinstance(x, int)
     return rffi.cast(lltype.Signed, _c.ntohs(x))
 
 def ntohl(x):
@@ -58,6 +60,7 @@
     return rffi.cast(lltype.Unsigned, _c.ntohl(x))
 
 def htons(x):
+    assert isinstance(x, int)
     return rffi.cast(lltype.Signed, _c.htons(x))
 
 def htonl(x):
@@ -220,7 +223,6 @@
         def get_protocol(self):
             a = self.lock(_c.sockaddr_ll)
             proto = rffi.getintfield(a, 'c_sll_protocol')
-            proto = rffi.cast(rffi.USHORT, proto)
             res = ntohs(proto)
             self.unlock()
             return res
@@ -256,7 +258,6 @@
     def __init__(self, host, port):
         makeipaddr(host, self)
         a = self.lock(_c.sockaddr_in)
-        port = rffi.cast(rffi.USHORT, port)
         rffi.setintfield(a, 'c_sin_port', htons(port))
         self.unlock()
 
@@ -268,7 +269,7 @@
 
     def get_port(self):
         a = self.lock(_c.sockaddr_in)
-        port = ntohs(a.c_sin_port)
+        port = ntohs(rffi.getintfield(a, 'c_sin_port'))
         self.unlock()
         return port
 
@@ -321,7 +322,7 @@
 
     def get_port(self):
         a = self.lock(_c.sockaddr_in6)
-        port = ntohs(a.c_sin6_port)
+        port = ntohs(rffi.getintfield(a, 'c_sin6_port'))
         self.unlock()
         return port
 
@@ -1135,18 +1136,18 @@
         paddr = h_addr_list[i]
     return (rffi.charp2str(hostent.c_h_name), aliases, address_list)
 
-def gethostbyname_ex(name, lock=dummy_lock):
+def gethostbyname_ex(name):
     # XXX use gethostbyname_r() if available instead of locks
     addr = gethostbyname(name)
-    with lock:
+    with _get_netdb_lock():
         hostent = _c.gethostbyname(name)
         return gethost_common(name, hostent, addr)
 
-def gethostbyaddr(ip, lock=dummy_lock):
+def gethostbyaddr(ip):
     # XXX use gethostbyaddr_r() if available, instead of locks
     addr = makeipaddr(ip)
     assert isinstance(addr, IPAddress)
-    with lock:
+    with _get_netdb_lock():
         p, size = addr.lock_in_addr()
         try:
             hostent = _c.gethostbyaddr(p, size, addr.family)
@@ -1154,6 +1155,36 @@
             addr.unlock()
         return gethost_common(ip, hostent, addr)
 
+# RPython magic to make _netdb_lock turn either into a regular
+# rthread.Lock or a rthread.DummyLock, depending on the config
+def _get_netdb_lock():
+    return rthread.dummy_lock
+
+class _Entry(ExtRegistryEntry):
+    _about_ = _get_netdb_lock
+
+    def compute_annotation(self):
+        config = self.bookkeeper.annotator.translator.config
+        if config.translation.thread:
+            fn = _get_netdb_lock_thread
+        else:
+            fn = _get_netdb_lock_nothread
+        return self.bookkeeper.immutablevalue(fn)
+
+def _get_netdb_lock_nothread():
+    return rthread.dummy_lock
+
+class _LockCache(object):
+    lock = None
+_lock_cache = _LockCache()
+
[email protected]
+def _get_netdb_lock_thread():
+    if _lock_cache.lock is None:
+        _lock_cache.lock = rthread.allocate_lock()
+    return _lock_cache.lock
+# done RPython magic
+
 def getaddrinfo(host, port_or_service,
                 family=AF_UNSPEC, socktype=0, proto=0, flags=0,
                 address_to_fill=None):
@@ -1201,13 +1232,13 @@
     servent = _c.getservbyname(name, proto)
     if not servent:
         raise RSocketError("service/proto not found")
-    port = rffi.cast(rffi.UINT, servent.c_s_port)
+    port = rffi.getintfield(servent, 'c_s_port')
     return ntohs(port)
 
 def getservbyport(port, proto=None):
     # This function is only called from pypy/module/_socket and the range of
     # port is checked there
-    port = rffi.cast(rffi.USHORT, port)
+    assert isinstance(port, int)
     servent = _c.getservbyport(htons(port), proto)
     if not servent:
         raise RSocketError("port/proto not found")
diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py
--- a/rpython/rlib/runicode.py
+++ b/rpython/rlib/runicode.py
@@ -8,8 +8,10 @@
 
 if rffi.sizeof(lltype.UniChar) == 4:
     MAXUNICODE = 0x10ffff
+    allow_surrogate_by_default = False
 else:
     MAXUNICODE = 0xffff
+    allow_surrogate_by_default = True
 
 BYTEORDER = sys.byteorder
 
@@ -122,7 +124,7 @@
 ]
 
 def str_decode_utf_8(s, size, errors, final=False,
-                     errorhandler=None, allow_surrogates=False):
+                     errorhandler=None, 
allow_surrogates=allow_surrogate_by_default):
     if errorhandler is None:
         errorhandler = default_unicode_error_decode
     result = UnicodeBuilder(size)
@@ -304,7 +306,7 @@
     result.append((chr((0x80 | (ch & 0x3f)))))
 
 def unicode_encode_utf_8(s, size, errors, errorhandler=None,
-                         allow_surrogates=False):
+                         allow_surrogates=allow_surrogate_by_default):
     if errorhandler is None:
         errorhandler = default_unicode_error_encode
     return unicode_encode_utf_8_impl(s, size, errors, errorhandler,
diff --git a/rpython/rlib/test/test_rsocket.py 
b/rpython/rlib/test/test_rsocket.py
--- a/rpython/rlib/test/test_rsocket.py
+++ b/rpython/rlib/test/test_rsocket.py
@@ -2,6 +2,7 @@
 from rpython.rlib import rsocket
 from rpython.rlib.rsocket import *
 import socket as cpy_socket
+from rpython.translator.c.test.test_genc import compile
 
 
 def setup_module(mod):
@@ -570,4 +571,17 @@
     for i in range(nthreads):
         threads[i].join()
     assert sum(result) == nthreads
- 
+
+def test_translate_netdb_lock():
+    def f():
+        gethostbyaddr("localhost")
+        return 0
+    fc = compile(f, [])
+    assert fc() == 0
+
+def test_translate_netdb_lock_thread():
+    def f():
+        gethostbyaddr("localhost")
+        return 0
+    fc = compile(f, [], thread=True)
+    assert fc() == 0
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
@@ -191,6 +191,11 @@
     def _is_varsize(self):
         return False
 
+    def _contains_value(self, value):
+        if self is Void:
+            return True
+        return isCompatibleType(typeOf(value), self)
+
 NFOUND = object()
 
 class ContainerType(LowLevelType):
diff --git a/rpython/rtyper/lltypesystem/rbytearray.py 
b/rpython/rtyper/lltypesystem/rbytearray.py
--- a/rpython/rtyper/lltypesystem/rbytearray.py
+++ b/rpython/rtyper/lltypesystem/rbytearray.py
@@ -38,12 +38,14 @@
             i += s.length()
         cls.ll_strsetitem_nonneg(s, i, item)
 
+    @staticmethod
     def ll_strsetitem_nonneg(s, i, item):
         chars = s.chars
         ll_assert(i >= 0, "negative str getitem index")
         ll_assert(i < len(chars), "str getitem index out of bound")
         chars[i] = chr(item)
 
+    @staticmethod
     def ll_stritem_nonneg(s, i):
         return ord(rstr.LLHelpers.ll_stritem_nonneg(s, i))
 
diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -270,6 +270,7 @@
 class LLHelpers(AbstractLLHelpers):
     from rpython.rtyper.annlowlevel import llstr, llunicode
 
+    @staticmethod
     @jit.elidable
     def ll_str_mul(s, times):
         if times < 0:
@@ -292,6 +293,7 @@
             i += j
         return newstr
 
+    @staticmethod
     @jit.elidable
     def ll_char_mul(ch, times):
         if typeOf(ch) is Char:
@@ -308,9 +310,11 @@
             j += 1
         return newstr
 
+    @staticmethod
     def ll_strlen(s):
         return len(s.chars)
 
+    @staticmethod
     @signature(types.any(), types.int(), returns=types.any())
     def ll_stritem_nonneg(s, i):
         chars = s.chars
@@ -318,6 +322,7 @@
         ll_assert(i < len(chars), "str getitem index out of bound")
         return chars[i]
 
+    @staticmethod
     def ll_chr2str(ch):
         if typeOf(ch) is Char:
             malloc = mallocstr
@@ -328,6 +333,7 @@
         return s
 
     # @jit.look_inside_iff(lambda str: jit.isconstant(len(str.chars)) and 
len(str.chars) == 1)
+    @staticmethod
     @jit.oopspec("str.str2unicode(str)")
     def ll_str2unicode(str):
         lgt = len(str.chars)
@@ -338,6 +344,7 @@
             s.chars[i] = cast_primitive(UniChar, str.chars[i])
         return s
 
+    @staticmethod
     def ll_str2bytearray(str):
         from rpython.rtyper.lltypesystem.rbytearray import BYTEARRAY
 
@@ -347,6 +354,7 @@
             b.chars[i] = str.chars[i]
         return b
 
+    @staticmethod
     @jit.elidable
     def ll_strhash(s):
         # unlike CPython, there is no reason to avoid to return -1
@@ -362,13 +370,17 @@
             s.hash = x
         return x
 
+    @staticmethod
     def ll_length(s):
         return len(s.chars)
 
+    @staticmethod
     def ll_strfasthash(s):
         return s.hash     # assumes that the hash is already computed
 
+    @staticmethod
     @jit.elidable
+    @jit.oopspec('stroruni.concat(s1, s2)')
     def ll_strconcat(s1, s2):
         len1 = s1.length()
         len2 = s2.length()
@@ -386,8 +398,8 @@
         else:
             newstr.copy_contents(s2, newstr, 0, len1, len2)
         return newstr
-    ll_strconcat.oopspec = 'stroruni.concat(s1, s2)'
 
+    @staticmethod
     @jit.elidable
     def ll_strip(s, ch, left, right):
         s_len = len(s.chars)
@@ -408,6 +420,7 @@
         s.copy_contents(s, result, lpos, 0, r_len)
         return result
 
+    @staticmethod
     @jit.elidable
     def ll_strip_default(s, left, right):
         s_len = len(s.chars)
@@ -428,6 +441,7 @@
         s.copy_contents(s, result, lpos, 0, r_len)
         return result
 
+    @staticmethod
     @jit.elidable
     def ll_strip_multiple(s, s2, left, right):
         s_len = len(s.chars)
@@ -448,6 +462,7 @@
         s.copy_contents(s, result, lpos, 0, r_len)
         return result
 
+    @staticmethod
     @jit.elidable
     def ll_upper(s):
         s_chars = s.chars
@@ -462,6 +477,7 @@
             i += 1
         return result
 
+    @staticmethod
     @jit.elidable
     def ll_lower(s):
         s_chars = s.chars
@@ -476,6 +492,7 @@
             i += 1
         return result
 
+    @staticmethod
     def ll_join(s, length, items):
         s_chars = s.chars
         s_len = len(s_chars)
@@ -509,7 +526,9 @@
             i += 1
         return result
 
+    @staticmethod
     @jit.elidable
+    @jit.oopspec('stroruni.cmp(s1, s2)')
     def ll_strcmp(s1, s2):
         if not s1 and not s2:
             return True
@@ -531,9 +550,10 @@
                 return diff
             i += 1
         return len1 - len2
-    ll_strcmp.oopspec = 'stroruni.cmp(s1, s2)'
 
+    @staticmethod
     @jit.elidable
+    @jit.oopspec('stroruni.equal(s1, s2)')
     def ll_streq(s1, s2):
         if s1 == s2:       # also if both are NULLs
             return True
@@ -551,8 +571,8 @@
                 return False
             j += 1
         return True
-    ll_streq.oopspec = 'stroruni.equal(s1, s2)'
 
+    @staticmethod
     @jit.elidable
     def ll_startswith(s1, s2):
         len1 = len(s1.chars)
@@ -569,11 +589,13 @@
 
         return True
 
+    @staticmethod
     def ll_startswith_char(s, ch):
         if not len(s.chars):
             return False
         return s.chars[0] == ch
 
+    @staticmethod
     @jit.elidable
     def ll_endswith(s1, s2):
         len1 = len(s1.chars)
@@ -591,11 +613,13 @@
 
         return True
 
+    @staticmethod
     def ll_endswith_char(s, ch):
         if not len(s.chars):
             return False
         return s.chars[len(s.chars) - 1] == ch
 
+    @staticmethod
     @jit.elidable
     @signature(types.any(), types.any(), types.int(), types.int(), 
returns=types.int())
     def ll_find_char(s, ch, start, end):
@@ -608,6 +632,7 @@
             i += 1
         return -1
 
+    @staticmethod
     @jit.elidable
     def ll_rfind_char(s, ch, start, end):
         if end > len(s.chars):
@@ -619,6 +644,7 @@
                 return i
         return -1
 
+    @staticmethod
     @jit.elidable
     def ll_count_char(s, ch, start, end):
         count = 0
@@ -631,6 +657,7 @@
             i += 1
         return count
 
+    @staticmethod
     @signature(types.any(), types.any(), types.int(), types.int(), 
returns=types.int())
     def ll_find(s1, s2, start, end):
         if start < 0:
@@ -646,6 +673,7 @@
 
         return LLHelpers.ll_search(s1, s2, start, end, FAST_FIND)
 
+    @staticmethod
     @signature(types.any(), types.any(), types.int(), types.int(), 
returns=types.int())
     def ll_rfind(s1, s2, start, end):
         if start < 0:
@@ -681,6 +709,7 @@
             res = 0
         return res
 
+    @staticmethod
     @jit.elidable
     def ll_search(s1, s2, start, end, mode):
         count = 0
@@ -768,6 +797,7 @@
             return -1
         return count
 
+    @staticmethod
     @signature(types.int(), types.any(), returns=types.any())
     @jit.look_inside_iff(lambda length, items: jit.loop_unrolling_heuristic(
         items, length))
@@ -802,6 +832,7 @@
             i += 1
         return result
 
+    @staticmethod
     @jit.look_inside_iff(lambda length, chars, RES: jit.isconstant(length) and 
jit.isvirtual(chars))
     def ll_join_chars(length, chars, RES):
         # no need to optimize this, will be replaced by string builder
@@ -821,6 +852,7 @@
             i += 1
         return result
 
+    @staticmethod
     @jit.oopspec('stroruni.slice(s1, start, stop)')
     @signature(types.any(), types.int(), types.int(), returns=types.any())
     @jit.elidable
@@ -836,9 +868,11 @@
         s1.copy_contents(s1, newstr, start, 0, lgt)
         return newstr
 
+    @staticmethod
     def ll_stringslice_startonly(s1, start):
         return LLHelpers._ll_stringslice(s1, start, len(s1.chars))
 
+    @staticmethod
     @signature(types.any(), types.int(), types.int(), returns=types.any())
     def ll_stringslice_startstop(s1, start, stop):
         if jit.we_are_jitted():
@@ -851,10 +885,12 @@
                 stop = len(s1.chars)
         return LLHelpers._ll_stringslice(s1, start, stop)
 
+    @staticmethod
     def ll_stringslice_minusone(s1):
         newlen = len(s1.chars) - 1
         return LLHelpers._ll_stringslice(s1, 0, newlen)
 
+    @staticmethod
     def ll_split_chr(LIST, s, c, max):
         chars = s.chars
         strlen = len(chars)
@@ -889,6 +925,7 @@
         item.copy_contents(s, item, i, 0, j - i)
         return res
 
+    @staticmethod
     def ll_split(LIST, s, c, max):
         count = 1
         if max == -1:
@@ -920,6 +957,7 @@
         item.copy_contents(s, item, prev_pos, 0, last - prev_pos)
         return res
 
+    @staticmethod
     def ll_rsplit_chr(LIST, s, c, max):
         chars = s.chars
         strlen = len(chars)
@@ -955,6 +993,7 @@
         item.copy_contents(s, item, j, 0, i - j)
         return res
 
+    @staticmethod
     def ll_rsplit(LIST, s, c, max):
         count = 1
         if max == -1:
@@ -986,6 +1025,7 @@
         item.copy_contents(s, item, 0, 0, prev_pos)
         return res
 
+    @staticmethod
     @jit.elidable
     def ll_replace_chr_chr(s, c1, c2):
         length = len(s.chars)
@@ -1001,6 +1041,7 @@
             j += 1
         return newstr
 
+    @staticmethod
     @jit.elidable
     def ll_contains(s, c):
         chars = s.chars
@@ -1012,6 +1053,7 @@
             i += 1
         return False
 
+    @staticmethod
     @jit.elidable
     def ll_int(s, base):
         if not 2 <= base <= 36:
@@ -1068,23 +1110,29 @@
     #   ll_build_push(x, next_string, n-1)
     #   s = ll_build_finish(x)
 
+    @staticmethod
     def ll_build_start(parts_count):
         return malloc(TEMP, parts_count)
 
+    @staticmethod
     def ll_build_push(builder, next_string, index):
         builder[index] = next_string
 
+    @staticmethod
     def ll_build_finish(builder):
         return LLHelpers.ll_join_strs(len(builder), builder)
 
+    @staticmethod
     @specialize.memo()
     def ll_constant(s):
         return string_repr.convert_const(s)
 
+    @staticmethod
     @specialize.memo()
     def ll_constant_unicode(s):
         return unicode_repr.convert_const(s)
 
+    @classmethod
     def do_stringformat(cls, hop, sourcevarsrepr):
         s_str = hop.args_s[0]
         assert s_str.is_constant()
@@ -1150,8 +1198,8 @@
 
         hop.exception_cannot_occur()   # to ignore the ZeroDivisionError of '%'
         return hop.gendirectcall(cls.ll_join_strs, size, vtemp)
-    do_stringformat = classmethod(do_stringformat)
 
+    @staticmethod
     @jit.dont_look_inside
     def ll_string2list(RESLIST, src):
         length = len(src.chars)
diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py
--- a/rpython/rtyper/rmodel.py
+++ b/rpython/rtyper/rmodel.py
@@ -2,8 +2,7 @@
 from rpython.flowspace.model import Constant
 from rpython.rtyper.error import TyperError, MissingRTypeOperation
 from rpython.rtyper.lltypesystem import lltype
-from rpython.rtyper.lltypesystem.lltype import (Void, Bool, typeOf,
-    LowLevelType, isCompatibleType)
+from rpython.rtyper.lltypesystem.lltype import Void, Bool, LowLevelType
 from rpython.tool.pairtype import pairtype, extendabletype, pair
 
 
@@ -120,14 +119,9 @@
 
     def convert_const(self, value):
         "Convert the given constant value to the low-level repr of 'self'."
-        if self.lowleveltype is not Void:
-            try:
-                realtype = typeOf(value)
-            except (AssertionError, AttributeError, TypeError):
-                realtype = '???'
-            if realtype != self.lowleveltype:
-                raise TyperError("convert_const(self = %r, value = %r)" % (
-                    self, value))
+        if not self.lowleveltype._contains_value(value):
+            raise TyperError("convert_const(self = %r, value = %r)" % (
+                self, value))
         return value
 
     def get_ll_eq_function(self):
@@ -356,18 +350,9 @@
         lltype = reqtype
     else:
         raise TypeError(repr(reqtype))
-    # Void Constants can hold any value;
-    # non-Void Constants must hold a correctly ll-typed value
-    if lltype is not Void:
-        try:
-            realtype = typeOf(value)
-        except (AssertionError, AttributeError):
-            realtype = '???'
-        if not isCompatibleType(realtype, lltype):
-            raise TyperError("inputconst(reqtype = %s, value = %s):\n"
-                             "expected a %r,\n"
-                             "     got a %r" % (reqtype, value,
-                                                lltype, realtype))
+    if not lltype._contains_value(value):
+        raise TyperError("inputconst(): expected a %r, got %r" %
+                         (lltype, value))
     c = Constant(value)
     c.concretetype = lltype
     return c
@@ -422,7 +407,8 @@
     def __ne__(self, other):
         return not (self == other)
 
-    def build_ll_dummy_value(self):
+    @property
+    def ll_dummy_value(self):
         TYPE = self.TYPE
         try:
             return self.rtyper.cache_dummy_values[TYPE]
@@ -435,8 +421,6 @@
             self.rtyper.cache_dummy_values[TYPE] = p
             return p
 
-    ll_dummy_value = property(build_ll_dummy_value)
-
 
 # logging/warning
 
diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py
--- a/rpython/rtyper/rstr.py
+++ b/rpython/rtyper/rstr.py
@@ -9,7 +9,6 @@
 from rpython.rtyper.rfloat import FloatRepr
 from rpython.tool.pairtype import pairtype, pair
 from rpython.tool.sourcetools import func_with_new_name
-from rpython.tool.staticmethods import StaticMethods
 from rpython.rlib.rstring import UnicodeBuilder
 
 
@@ -800,10 +799,8 @@
 #  get flowed and annotated, mostly with SomePtr.
 #
 
-# this class contains low level helpers used both by lltypesystem
-class AbstractLLHelpers:
-    __metaclass__ = StaticMethods
-
+class AbstractLLHelpers(object):
+    @staticmethod
     def ll_isdigit(s):
         from rpython.rtyper.annlowlevel import hlstr
 
@@ -815,6 +812,7 @@
                 return False
         return True
 
+    @staticmethod
     def ll_isalpha(s):
         from rpython.rtyper.annlowlevel import hlstr
 
@@ -826,6 +824,7 @@
                 return False
         return True
 
+    @staticmethod
     def ll_isalnum(s):
         from rpython.rtyper.annlowlevel import hlstr
 
@@ -837,14 +836,17 @@
                 return False
         return True
 
+    @staticmethod
     def ll_char_isspace(ch):
         c = ord(ch)
         return c == 32 or (9 <= c <= 13)   # c in (9, 10, 11, 12, 13, 32)
 
+    @staticmethod
     def ll_char_isdigit(ch):
         c = ord(ch)
         return c <= 57 and c >= 48
 
+    @staticmethod
     def ll_char_isalpha(ch):
         c = ord(ch)
         if c >= 97:
@@ -852,6 +854,7 @@
         else:
             return 65 <= c <= 90
 
+    @staticmethod
     def ll_char_isalnum(ch):
         c = ord(ch)
         if c >= 65:
@@ -862,47 +865,54 @@
         else:
             return 48 <= c <= 57
 
+    @staticmethod
     def ll_char_isupper(ch):
         c = ord(ch)
         return 65 <= c <= 90
 
+    @staticmethod
     def ll_char_islower(ch):
         c = ord(ch)
         return 97 <= c <= 122
 
+    @staticmethod
     def ll_upper_char(ch):
         if 'a' <= ch <= 'z':
             ch = chr(ord(ch) - 32)
         return ch
 
+    @staticmethod
     def ll_lower_char(ch):
         if 'A' <= ch <= 'Z':
             ch = chr(ord(ch) + 32)
         return ch
 
+    @staticmethod
     def ll_char_hash(ch):
         return ord(ch)
 
+    @staticmethod
     def ll_unichar_hash(ch):
         return ord(ch)
 
+    @classmethod
     def ll_str_is_true(cls, s):
         # check if a string is True, allowing for None
         return bool(s) and cls.ll_strlen(s) != 0
-    ll_str_is_true = classmethod(ll_str_is_true)
 
+    @classmethod
     def ll_stritem_nonneg_checked(cls, s, i):
         if i >= cls.ll_strlen(s):
             raise IndexError
         return cls.ll_stritem_nonneg(s, i)
-    ll_stritem_nonneg_checked = classmethod(ll_stritem_nonneg_checked)
 
+    @classmethod
     def ll_stritem(cls, s, i):
         if i < 0:
             i += cls.ll_strlen(s)
         return cls.ll_stritem_nonneg(s, i)
-    ll_stritem = classmethod(ll_stritem)
 
+    @classmethod
     def ll_stritem_checked(cls, s, i):
         length = cls.ll_strlen(s)
         if i < 0:
@@ -910,8 +920,8 @@
         if i >= length or i < 0:
             raise IndexError
         return cls.ll_stritem_nonneg(s, i)
-    ll_stritem_checked = classmethod(ll_stritem_checked)
 
+    @staticmethod
     def parse_fmt_string(fmt):
         # we support x, d, s, f, [r]
         it = iter(fmt)
@@ -937,6 +947,7 @@
             r.append(curstr)
         return r
 
+    @staticmethod
     def ll_float(ll_str):
         from rpython.rtyper.annlowlevel import hlstr
         from rpython.rlib.rfloat import rstring_to_float
@@ -961,6 +972,7 @@
         assert end >= 0
         return rstring_to_float(s[beg:end + 1])
 
+    @classmethod
     def ll_splitlines(cls, LIST, ll_str, keep_newlines):
         from rpython.rtyper.annlowlevel import hlstr
         s = hlstr(ll_str)
@@ -991,4 +1003,3 @@
             item = cls.ll_stringslice_startstop(ll_str, j, strlen)
             res.ll_setitem_fast(list_length, item)
         return res
-    ll_splitlines = classmethod(ll_splitlines)
diff --git a/rpython/tool/staticmethods.py b/rpython/tool/staticmethods.py
deleted file mode 100644
--- a/rpython/tool/staticmethods.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import types
-class AbstractMethods(type):
-    def __new__(cls, cls_name, bases, cls_dict):
-        for key, value in cls_dict.iteritems():
-            if isinstance(value, types.FunctionType):
-                cls_dict[key] = cls.decorator(value)
-        return type.__new__(cls, cls_name, bases, cls_dict)
-
-
-class StaticMethods(AbstractMethods):
-    """
-    Metaclass that turns plain methods into staticmethods.
-    """
-    decorator = staticmethod
diff --git a/rpython/translator/platform/__init__.py 
b/rpython/translator/platform/__init__.py
--- a/rpython/translator/platform/__init__.py
+++ b/rpython/translator/platform/__init__.py
@@ -354,8 +354,10 @@
     platform = pick_platform(new_platform, cc)
     if not platform:
         raise ValueError("pick_platform(%r, %s) failed"%(new_platform, cc))
-    log.msg("Set platform with %r cc=%s, using cc=%r" % (new_platform, cc,
-                    getattr(platform, 'cc','Unknown')))
+    log.msg("Set platform with %r cc=%s, using cc=%r, version=%r" % 
(new_platform, cc,
+                    getattr(platform, 'cc','Unknown'),
+                    getattr(platform, 'version','Unknown'),
+    ))
 
     if new_platform == 'host':
         global host
diff --git a/rpython/translator/platform/windows.py 
b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -14,9 +14,11 @@
     if not cc:
         cc = os.environ.get('CC','')
     if not cc:
-        return MsvcPlatform(cc=cc, x64=x64_flag)
+        return MsvcPlatform(x64=x64_flag)
     elif cc.startswith('mingw') or cc == 'gcc':
         return MingwPlatform(cc)
+    else:
+        return MsvcPlatform(cc=cc, x64=x64_flag)
     try:
         subprocess.check_output([cc, '--version'])
     except:
@@ -108,11 +110,14 @@
 
     def __init__(self, cc=None, x64=False):
         self.x64 = x64
-        msvc_compiler_environ = find_msvc_env(x64)
-        Platform.__init__(self, 'cl.exe')
-        if msvc_compiler_environ:
-            self.c_environ = os.environ.copy()
-            self.c_environ.update(msvc_compiler_environ)
+        if cc is None:
+            msvc_compiler_environ = find_msvc_env(x64)
+            Platform.__init__(self, 'cl.exe')
+            if msvc_compiler_environ:
+                self.c_environ = os.environ.copy()
+                self.c_environ.update(msvc_compiler_environ)
+        else:
+            self.cc = cc
 
         # detect version of current compiler
         returncode, stdout, stderr = _run_subprocess(self.cc, '',
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to