[pypy-commit] pypy jit-short_from_state: hg merge default

hakanardo noreply at buildbot.pypy.org
Wed Aug 17 20:34:41 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short_from_state
Changeset: r46565:f4cbb977750a
Date: 2011-08-16 18:46 +0200
http://bitbucket.org/pypy/pypy/changeset/f4cbb977750a/

Log:	hg merge default

diff --git a/lib-python/modified-2.7/test/regrtest.py b/lib-python/modified-2.7/test/regrtest.py
--- a/lib-python/modified-2.7/test/regrtest.py
+++ b/lib-python/modified-2.7/test/regrtest.py
@@ -1403,7 +1403,26 @@
         test_zipimport
         test_zlib
         """,
-    'openbsd3':
+    'openbsd4':
+        """
+        test_ascii_formatd
+        test_bsddb
+        test_bsddb3
+        test_ctypes
+        test_dl
+        test_epoll
+        test_gdbm
+        test_locale
+        test_normalization
+        test_ossaudiodev
+        test_pep277
+        test_tcl
+        test_tk
+        test_ttk_guionly
+        test_ttk_textonly
+        test_multiprocessing
+        """,
+    'openbsd5':
         """
         test_ascii_formatd
         test_bsddb
diff --git a/lib-python/modified-2.7/test/test_fcntl.py b/lib-python/modified-2.7/test/test_fcntl.py
new file mode 100644
--- /dev/null
+++ b/lib-python/modified-2.7/test/test_fcntl.py
@@ -0,0 +1,108 @@
+"""Test program for the fcntl C module.
+
+OS/2+EMX doesn't support the file locking operations.
+
+"""
+import os
+import struct
+import sys
+import unittest
+from test.test_support import (verbose, TESTFN, unlink, run_unittest,
+    import_module)
+
+# Skip test if no fnctl module.
+fcntl = import_module('fcntl')
+
+
+# TODO - Write tests for flock() and lockf().
+
+def get_lockdata():
+    if sys.platform.startswith('atheos'):
+        start_len = "qq"
+    else:
+        try:
+            os.O_LARGEFILE
+        except AttributeError:
+            start_len = "ll"
+        else:
+            start_len = "qq"
+
+    if sys.platform in ('netbsd1', 'netbsd2', 'netbsd3',
+                        'Darwin1.2', 'darwin',
+                        'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
+                        'freebsd6', 'freebsd7', 'freebsd8',
+                        'bsdos2', 'bsdos3', 'bsdos4',
+                        'openbsd', 'openbsd2', 'openbsd3', 'openbsd4', 'openbsd5'):
+        if struct.calcsize('l') == 8:
+            off_t = 'l'
+            pid_t = 'i'
+        else:
+            off_t = 'lxxxx'
+            pid_t = 'l'
+        lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0,
+                               fcntl.F_WRLCK, 0)
+    elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']:
+        lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
+    elif sys.platform in ['os2emx']:
+        lockdata = None
+    else:
+        lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
+    if lockdata:
+        if verbose:
+            print 'struct.pack: ', repr(lockdata)
+    return lockdata
+
+lockdata = get_lockdata()
+
+
+class TestFcntl(unittest.TestCase):
+
+    def setUp(self):
+        self.f = None
+
+    def tearDown(self):
+        if self.f and not self.f.closed:
+            self.f.close()
+        unlink(TESTFN)
+
+    def test_fcntl_fileno(self):
+        # the example from the library docs
+        self.f = open(TESTFN, 'w')
+        rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
+        if verbose:
+            print 'Status from fcntl with O_NONBLOCK: ', rv
+        if sys.platform not in ['os2emx']:
+            rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata)
+            if verbose:
+                print 'String from fcntl with F_SETLKW: ', repr(rv)
+        self.f.close()
+
+    def test_fcntl_file_descriptor(self):
+        # again, but pass the file rather than numeric descriptor
+        self.f = open(TESTFN, 'w')
+        rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK)
+        if sys.platform not in ['os2emx']:
+            rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata)
+        self.f.close()
+
+    def test_fcntl_64_bit(self):
+        # Issue #1309352: fcntl shouldn't fail when the third arg fits in a
+        # C 'long' but not in a C 'int'.
+        try:
+            cmd = fcntl.F_NOTIFY
+            # This flag is larger than 2**31 in 64-bit builds
+            flags = fcntl.DN_MULTISHOT
+        except AttributeError:
+            self.skipTest("F_NOTIFY or DN_MULTISHOT unavailable")
+        fd = os.open(os.path.dirname(os.path.abspath(TESTFN)), os.O_RDONLY)
+        try:
+            fcntl.fcntl(fd, cmd, flags)
+        finally:
+            os.close(fd)
+
+
+def test_main():
+    run_unittest(TestFcntl)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/lib-python/modified-2.7/test/test_tempfile.py b/lib-python/modified-2.7/test/test_tempfile.py
--- a/lib-python/modified-2.7/test/test_tempfile.py
+++ b/lib-python/modified-2.7/test/test_tempfile.py
@@ -23,8 +23,8 @@
 
 # TEST_FILES may need to be tweaked for systems depending on the maximum
 # number of files that can be opened at one time (see ulimit -n)
-if sys.platform in ('openbsd3', 'openbsd4'):
-    TEST_FILES = 48
+if sys.platform.startswith("openbsd"):
+    TEST_FILES = 64 # ulimit -n defaults to 128 for normal users
 else:
     TEST_FILES = 100
 
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -724,13 +724,12 @@
             self.statement.reset()
             raise self.connection._get_exception(ret)
 
-        if self.statement.kind == "DQL":
-            if ret == SQLITE_ROW:
-                self.statement._build_row_cast_map()
-                self.statement._readahead()
-            else:
-                self.statement.item = None
-                self.statement.exhausted = True
+        if self.statement.kind == "DQL"and ret == SQLITE_ROW:
+            self.statement._build_row_cast_map()
+            self.statement._readahead()
+        else:
+            self.statement.item = None
+            self.statement.exhausted = True
 
         if self.statement.kind in ("DML", "DDL"):
             self.statement.reset()
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -308,9 +308,6 @@
             clsdef = clsdef.commonbase(cdef)
     return SomeInstance(clsdef)
 
-def robjmodel_we_are_translated():
-    return immutablevalue(True)
-
 def robjmodel_r_dict(s_eqfn, s_hashfn, s_force_non_null=None):
     if s_force_non_null is None:
         force_non_null = False
@@ -376,8 +373,6 @@
 
 BUILTIN_ANALYZERS[pypy.rlib.rarithmetic.intmask] = rarith_intmask
 BUILTIN_ANALYZERS[pypy.rlib.objectmodel.instantiate] = robjmodel_instantiate
-BUILTIN_ANALYZERS[pypy.rlib.objectmodel.we_are_translated] = (
-    robjmodel_we_are_translated)
 BUILTIN_ANALYZERS[pypy.rlib.objectmodel.r_dict] = robjmodel_r_dict
 BUILTIN_ANALYZERS[pypy.rlib.objectmodel.hlinvoke] = robjmodel_hlinvoke
 BUILTIN_ANALYZERS[pypy.rlib.objectmodel.keepalive_until_here] = robjmodel_keepalive_until_here
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -88,6 +88,13 @@
 
     _stackless
 
+  Note that only some of these modules are built-in in a typical
+  CPython installation, and the rest is from non built-in extension
+  modules.  This means that e.g. ``import parser`` will, on CPython,
+  find a local file ``parser.py``, while ``import sys`` will not find a
+  local file ``sys.py``.  In PyPy the difference does not exist: all
+  these modules are built-in.
+
 * Supported by being rewritten in pure Python (possibly using ``ctypes``):
   see the `lib_pypy/`_ directory.  Examples of modules that we
   support this way: ``ctypes``, ``cPickle``, ``cmath``, ``dbm``, ``datetime``...
diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst
--- a/pypy/doc/garbage_collection.rst
+++ b/pypy/doc/garbage_collection.rst
@@ -147,7 +147,7 @@
 You can read more about them at the start of
 `pypy/rpython/memory/gc/minimark.py`_.
 
-In more details:
+In more detail:
 
 - The small newly malloced objects are allocated in the nursery (case 1).
   All objects living in the nursery are "young".
diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -32,7 +32,10 @@
 .. _`windows document`: windows.html
 
 You can translate the whole of PyPy's Python interpreter to low level C code,
-or `CLI code`_.
+or `CLI code`_.  If you intend to build using gcc, check to make sure that
+the version you have is not 4.2 or you will run into `this bug`_.
+
+.. _`this bug`: https://bugs.launchpad.net/ubuntu/+source/gcc-4.2/+bug/187391
 
 1. First `download a pre-built PyPy`_ for your architecture which you will
    use to translate your Python interpreter.  It is, of course, possible to
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -138,6 +138,11 @@
         return self.space.wrap(rffi.charp2str(self._issuer))
 
     def __del__(self):
+        self.enqueue_for_destruction(self.space, SSLObject.destructor,
+                                     '__del__() method of ')
+
+    def destructor(self):
+        assert isinstance(self, SSLObject)
         if self.peer_cert:
             libssl_X509_free(self.peer_cert)
         if self.ssl:
diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -63,7 +63,7 @@
         _ssl.RAND_egd("entropy")
 
     def test_sslwrap(self):
-        import _ssl, _socket, sys
+        import _ssl, _socket, sys, gc
         if sys.platform == 'darwin':
             skip("hangs indefinitely on OSX (also on CPython)")
         s = _socket.socket()
@@ -73,15 +73,19 @@
             assert exc.value.errno == 2 # Cannot find file (=not a socket)
         else:
             assert exc.value.errno == 32 # Broken pipe
+        del exc, ss, s
+        gc.collect()     # force the destructor() to be called now
 
     def test_async_closed(self):
-        import _ssl, _socket
+        import _ssl, _socket, gc
         s = _socket.socket()
         s.settimeout(3)
         ss = _ssl.sslwrap(s, 0)
         s.close()
         exc = raises(_ssl.SSLError, ss.write, "data")
         assert exc.value.strerror == "Underlying socket has been closed."
+        del exc, ss, s
+        gc.collect()     # force the destructor() to be called now
 
 
 class AppTestConnectedSSL:
@@ -104,42 +108,47 @@
             """)
 
     def test_connect(self):
-        import socket
+        import socket, gc
         ss = socket.ssl(self.s)
         self.s.close()
+        del ss; gc.collect()
 
     def test_server(self):
-        import socket
+        import socket, gc
         ss = socket.ssl(self.s)
         assert isinstance(ss.server(), str)
         self.s.close()
+        del ss; gc.collect()
 
     def test_issuer(self):
-        import socket
+        import socket, gc
         ss = socket.ssl(self.s)
         assert isinstance(ss.issuer(), str)
         self.s.close()
+        del ss; gc.collect()
 
     def test_write(self):
-        import socket
+        import socket, gc
         ss = socket.ssl(self.s)
         raises(TypeError, ss.write, 123)
         num_bytes = ss.write("hello\n")
         assert isinstance(num_bytes, int)
         assert num_bytes >= 0
         self.s.close()
+        del ss; gc.collect()
 
     def test_read(self):
-        import socket
+        import socket, gc
         ss = socket.ssl(self.s)
         raises(TypeError, ss.read, "foo")
         ss.write("hello\n")
         data = ss.read()
         assert isinstance(data, str)
         self.s.close()
+        del ss; gc.collect()
 
     def test_read_upto(self):
-        import socket
+        import socket, gc
         ss = socket.ssl(self.s)
         raises(TypeError, ss.read, "foo")
         ss.write("hello\n")
@@ -148,15 +157,17 @@
         assert len(data) == 10
         assert ss.pending() > 50 # many more bytes to read
         self.s.close()
+        del ss; gc.collect()
 
     def test_shutdown(self):
-        import socket, ssl, sys
+        import socket, ssl, sys, gc
         if sys.platform == 'darwin':
             skip("get also on CPython: error: [Errno 0]")
         ss = socket.ssl(self.s)
         ss.write("hello\n")
         assert ss.shutdown() is self.s._sock
         raises(ssl.SSLError, ss.write, "hello\n")
+        del ss; gc.collect()
 
 class AppTestConnectedSSL_Timeout(AppTestConnectedSSL):
     # Same tests, with a socket timeout
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -38,12 +38,10 @@
                 w_initializer = __args__.arguments_w[0]
                 if space.type(w_initializer) is space.w_str:
                     a.fromstring(space.str_w(w_initializer))
-                elif space.type(w_initializer) is space.w_unicode:
-                    a.fromsequence(w_initializer)
                 elif space.type(w_initializer) is space.w_list:
                     a.fromlist(w_initializer)
                 else:
-                    a.extend(w_initializer)
+                    a.extend(w_initializer, True)
             break
     else:
         msg = 'bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)'
@@ -287,7 +285,7 @@
                 self.setlen(s)
                 raise
 
-        def extend(self, w_iterable):
+        def extend(self, w_iterable, accept_different_array=False):
             space = self.space
             if isinstance(w_iterable, W_Array):
                 oldlen = self.len
@@ -300,7 +298,8 @@
                     self.buffer[oldlen + i] = w_iterable.buffer[i]
                     i += 1
                 self.setlen(oldlen + i)
-            elif isinstance(w_iterable, W_ArrayBase):
+            elif (not accept_different_array
+                  and isinstance(w_iterable, W_ArrayBase)):
                 msg = "can only extend with array of same kind"
                 raise OperationError(space.w_TypeError, space.wrap(msg))
             else:
diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -64,6 +64,10 @@
             assert self.array(tc).typecode == tc
             raises(TypeError, self.array, tc, None)
 
+        a = self.array('i', (1, 2, 3))
+        b = self.array('h', a)
+        assert list(b) == [1, 2, 3]
+
     def test_value_range(self):
         import sys
         values = (-129, 128, -128, 127, 0, 255, -1, 256,
diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py
--- a/pypy/module/bz2/interp_bz2.py
+++ b/pypy/module/bz2/interp_bz2.py
@@ -123,9 +123,9 @@
     def _bzs_total_out(bzs):
         return bzs.total_out
 
-def external(name, args, result):
+def external(name, args, result, **kwds):
     return rffi.llexternal(name, args, result, compilation_info=
-                           CConfig._compilation_info_)
+                           CConfig._compilation_info_, **kwds)
 
 # the least but one parameter should be rffi.VOIDP but it's not used
 # so I trick the compiler to not complain about constanst pointer passed
@@ -143,11 +143,13 @@
                                        rffi.INT], lltype.Void)
 BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT,
                               rffi.INT, rffi.INT], rffi.INT)
-BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT)
+BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT,
+                             threadsafe=False)
 BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT)
 BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT,
                                                          rffi.INT], rffi.INT)
-BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT)
+BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT,
+                               threadsafe=False)
 BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT)
 
 def _catch_bz2_error(space, bzerror):
diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py
--- a/pypy/module/fcntl/test/test_fcntl.py
+++ b/pypy/module/fcntl/test/test_fcntl.py
@@ -47,7 +47,8 @@
                             'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
                             'freebsd6', 'freebsd7', 'freebsd8', 'freebsd9',
                             'bsdos2', 'bsdos3', 'bsdos4',
-                            'openbsd', 'openbsd2', 'openbsd3'):
+                            'openbsd', 'openbsd2', 'openbsd3', 'openbsd4',
+                            'openbsd5'):
             if struct.calcsize('l') == 8:
                 off_t = 'l'
                 pid_t = 'i'
@@ -181,7 +182,7 @@
 
     def test_large_flag(self):
         import sys
-        if sys.platform == "darwin":
+        if sys.platform == "darwin" or sys.platform.startswith("openbsd"):
             skip("Mac OS doesn't have any large flag in fcntl.h")
         import fcntl, sys
         if sys.maxint == 2147483647:
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -878,7 +878,8 @@
         code_w = parse_source_module(space, pathname, source)
 
         if space.config.objspace.usepycfiles and write_pyc:
-            write_compiled_module(space, code_w, cpathname, mode, mtime)
+            if not space.is_true(space.sys.get('dont_write_bytecode')):
+                write_compiled_module(space, code_w, cpathname, mode, mtime)
 
     update_code_filenames(space, code_w, pathname)
     exec_code_module(space, w_mod, code_w)
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -769,6 +769,27 @@
         cpathname = udir.join('test.pyc')
         assert not cpathname.check()
 
+    def test_load_source_module_dont_write_bytecode(self):
+        space = self.space
+        w_modulename = space.wrap('somemodule')
+        w_mod = space.wrap(Module(space, w_modulename))
+        pathname = _testfilesource()
+        stream = streamio.open_file_as_stream(pathname, "r")
+        try:
+            space.setattr(space.sys, space.wrap('dont_write_bytecode'),
+                          space.w_True)
+            w_ret = importing.load_source_module(space,
+                                                 w_modulename,
+                                                 w_mod,
+                                                 pathname,
+                                                 stream.readall())
+        finally:
+            space.setattr(space.sys, space.wrap('dont_write_bytecode'),
+                          space.w_False)
+            stream.close()
+        cpathname = udir.join('test.pyc')
+        assert not cpathname.check()
+
     def test_load_source_module_syntaxerror(self):
         # No .pyc file on SyntaxError
         space = self.space
diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -317,7 +317,7 @@
 XML_ParserCreateNS = expat_external(
     'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser)
 XML_ParserFree = expat_external(
-    'XML_ParserFree', [XML_Parser], lltype.Void)
+    'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False)
 XML_SetUserData = expat_external(
     'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void)
 def XML_GetUserData(parser):
diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -98,6 +98,7 @@
     thread.release_NOAUTO(spacestate.ll_GIL)
     set_errno(e)
 before_external_call._gctransformer_hint_cannot_collect_ = True
+before_external_call._dont_reach_me_in_del_ = True
 
 def after_external_call():
     e = get_errno()
@@ -106,6 +107,7 @@
     spacestate.after_thread_switch()
     set_errno(e)
 after_external_call._gctransformer_hint_cannot_collect_ = True
+after_external_call._dont_reach_me_in_del_ = True
 
 # The _gctransformer_hint_cannot_collect_ hack is needed for
 # translations in which the *_external_call() functions are not inlined.
diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py
--- a/pypy/module/thread/ll_thread.py
+++ b/pypy/module/thread/ll_thread.py
@@ -51,9 +51,9 @@
 
 c_thread_lock_init = llexternal('RPyThreadLockInit', [TLOCKP], rffi.INT,
                                 threadsafe=False)   # may add in a global list
-c_thread_lock_dealloc = llexternal('RPyOpaqueDealloc_ThreadLock', [TLOCKP],
-                                  lltype.Void,
-                                  threadsafe=True)
+c_thread_lock_dealloc_NOAUTO = llexternal('RPyOpaqueDealloc_ThreadLock',
+                                          [TLOCKP], lltype.Void,
+                                          _nowrapper=True)
 c_thread_acquirelock = llexternal('RPyThreadAcquireLock', [TLOCKP, rffi.INT],
                                   rffi.INT,
                                   threadsafe=True)    # release the GIL
@@ -158,9 +158,9 @@
     return ll_lock
 
 def free_ll_lock(ll_lock):
-    c_thread_acquirelock(ll_lock, 0)
-    c_thread_releaselock(ll_lock)
-    c_thread_lock_dealloc(ll_lock)
+    acquire_NOAUTO(ll_lock, False)
+    release_NOAUTO(ll_lock)
+    c_thread_lock_dealloc_NOAUTO(ll_lock)
     lltype.free(ll_lock, flavor='raw', track_allocation=False)
 
 def acquire_NOAUTO(ll_lock, flag):
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -252,4 +252,6 @@
 def interrupt_main(space):
     """Raise a KeyboardInterrupt in the main thread.
 A subthread can use this function to interrupt the main thread."""
+    if space.check_signal_action is None:   # no signal module!
+        raise OperationError(space.w_KeyboardInterrupt, space.w_None)
     space.check_signal_action.set_interrupt()
diff --git a/pypy/module/thread/test/test_ll_thread.py b/pypy/module/thread/test/test_ll_thread.py
--- a/pypy/module/thread/test/test_ll_thread.py
+++ b/pypy/module/thread/test/test_ll_thread.py
@@ -52,6 +52,13 @@
             assert get_ident() == state.z.ident
             state.seen_value = state.z.value
             state.z = None
+            # I think that we would need here a memory barrier in order
+            # to make the test pass reliably.  The issue is that the
+            # main thread may see 'state.done = 1' before seeing the
+            # effect of the other assignments done above.  For now let's
+            # emulate the write barrier by doing a system call and
+            # waiting a bit...
+            time.sleep(0.012)
             state.done = 1
 
         def g(i):
diff --git a/pypy/objspace/flow/specialcase.py b/pypy/objspace/flow/specialcase.py
--- a/pypy/objspace/flow/specialcase.py
+++ b/pypy/objspace/flow/specialcase.py
@@ -4,6 +4,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.tool.cache import Cache
 from pypy.rlib.rarithmetic import r_uint
+from pypy.rlib.objectmodel import we_are_translated
 import py
 
 def sc_import(space, fn, args):
@@ -129,6 +130,9 @@
         return Constant(r_uint(w_value.value))
     return space.do_operation('simple_call', space.wrap(r_uint), w_value)
 
+def sc_we_are_translated(space, we_are_translated, args):
+    return Constant(True)
+
 def setup(space):
     # fn = pyframe.normalize_exception.get_function(space)
     # this is now routed through the objspace, directly.
@@ -144,3 +148,5 @@
     # (normally, the 32-bit constant is a long, and is not allowed to
     # show up in the flow graphs at all)
     space.specialcases[r_uint] = sc_r_uint
+    # special case we_are_translated() to return True
+    space.specialcases[we_are_translated] = sc_we_are_translated
diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py
--- a/pypy/objspace/flow/test/test_objspace.py
+++ b/pypy/objspace/flow/test/test_objspace.py
@@ -501,6 +501,24 @@
             assert op.args[1].value == 3
 
     #__________________________________________________________
+
+    def wearetranslated(x):
+        from pypy.rlib.objectmodel import we_are_translated
+        if we_are_translated():
+            return x
+        else:
+            some_name_error_here
+
+    def test_wearetranslated(self):
+        x = self.codetest(self.wearetranslated)
+        from pypy.translator.simplify import join_blocks
+        join_blocks(x)
+        # check that 'x' is an empty graph
+        assert len(x.startblock.operations) == 0
+        assert len(x.startblock.exits) == 1
+        assert x.startblock.exits[0].target is x.returnblock
+
+    #__________________________________________________________
     def jump_target_specialization(x):
         if x:
             n = 5
diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -1000,45 +1000,57 @@
 
     def test_mix_classes(self):
         import __pypy__
-        class A(object):
-            def f(self):
-                return 42
-        class B(object):
-            def f(self):
-                return 43
-        class C(object):
-            def f(self):
-                return 44
-        l = [A(), B(), C()] * 10
-        __pypy__.reset_method_cache_counter()
-        # 'exec' to make sure that a.f() is compiled with CALL_METHOD
-        exec """for i, a in enumerate(l):
-                    assert a.f() == 42 + i % 3
-"""
-        cache_counter = __pypy__.mapdict_cache_counter("f")
-        assert cache_counter[0] >= 15
-        assert cache_counter[1] >= 3 # should be (27, 3)
-        assert sum(cache_counter) == 30
+        seen = []
+        for i in range(20):
+            class A(object):
+                def f(self):
+                    return 42
+            class B(object):
+                def f(self):
+                    return 43
+            class C(object):
+                def f(self):
+                    return 44
+            l = [A(), B(), C()] * 10
+            __pypy__.reset_method_cache_counter()
+            # 'exec' to make sure that a.f() is compiled with CALL_METHOD
+            exec """for i, a in enumerate(l):
+                        assert a.f() == 42 + i % 3
+            """ in locals()
+            cache_counter = __pypy__.mapdict_cache_counter("f")
+            if cache_counter == (27, 3):
+                break
+            # keep them alive, to make sure that on the
+            # next try they have difference addresses
+            seen.append((l, cache_counter))
+        else:
+            assert 0, "failed: got %r" % ([got[1] for got in seen],)
 
     def test_mix_classes_attribute(self):
         import __pypy__
-        class A(object):
-            def __init__(self):
-                self.x = 42
-        class B(object):
-            def __init__(self):
-                self.x = 43
-        class C(object):
-            def __init__(self):
-                self.x = 44
-        l = [A(), B(), C()] * 10
-        __pypy__.reset_method_cache_counter()
-        for i, a in enumerate(l):
-            assert a.x == 42 + i % 3
-        cache_counter = __pypy__.mapdict_cache_counter("x")
-        assert cache_counter[0] >= 15
-        assert cache_counter[1] >= 3 # should be (27, 3)
-        assert sum(cache_counter) == 30
+        seen = []
+        for i in range(20):
+            class A(object):
+                def __init__(self):
+                    self.x = 42
+            class B(object):
+                def __init__(self):
+                    self.x = 43
+            class C(object):
+                def __init__(self):
+                    self.x = 44
+            l = [A(), B(), C()] * 10
+            __pypy__.reset_method_cache_counter()
+            for i, a in enumerate(l):
+                assert a.x == 42 + i % 3
+            cache_counter = __pypy__.mapdict_cache_counter("x")
+            if cache_counter == (27, 3):
+                break
+            # keep them alive, to make sure that on the
+            # next try they have difference addresses
+            seen.append((l, cache_counter))
+        else:
+            assert 0, "failed: got %r" % ([got[1] for got in seen],)
 
 class TestDictSubclassShortcutBug(object):
     def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -211,6 +211,20 @@
         assert u'hello '.capitalize() == u'Hello '
         assert u'aaaa'.capitalize() == u'Aaaa'
         assert u'AaAa'.capitalize() == u'Aaaa'
+        # check that titlecased chars are lowered correctly
+        # \u1ffc is the titlecased char
+        assert (u'\u1ff3\u1ff3\u1ffc\u1ffc'.capitalize() ==
+                u'\u1ffc\u1ff3\u1ff3\u1ff3')
+        # check with cased non-letter chars
+        assert (u'\u24c5\u24ce\u24c9\u24bd\u24c4\u24c3'.capitalize() ==
+                u'\u24c5\u24e8\u24e3\u24d7\u24de\u24dd')
+        assert (u'\u24df\u24e8\u24e3\u24d7\u24de\u24dd'.capitalize() ==
+                u'\u24c5\u24e8\u24e3\u24d7\u24de\u24dd')
+        assert u'\u2160\u2161\u2162'.capitalize() == u'\u2160\u2171\u2172'
+        assert u'\u2170\u2171\u2172'.capitalize() == u'\u2160\u2171\u2172'
+        # check with Ll chars with no upper - nothing changes here
+        assert (u'\u019b\u1d00\u1d86\u0221\u1fb7'.capitalize() ==
+                u'\u019b\u1d00\u1d86\u0221\u1fb7')
 
     def test_rjust(self):
         s = u"abc"
@@ -834,4 +848,4 @@
         assert type(b) is unicode
         assert b == u'hello \u1234'
 
-        assert u'%s' % S(u'mar\xe7') == u'mar\xe7'
\ No newline at end of file
+        assert u'%s' % S(u'mar\xe7') == u'mar\xe7'
diff --git a/pypy/rlib/_rsocket_rffi.py b/pypy/rlib/_rsocket_rffi.py
--- a/pypy/rlib/_rsocket_rffi.py
+++ b/pypy/rlib/_rsocket_rffi.py
@@ -455,9 +455,9 @@
 #    eci = ExternalCompilationInfo(includes=includes, libraries=libraries,
 #                                  separate_module_sources=sources)
 
-def external(name, args, result):
+def external(name, args, result, **kwds):
     return rffi.llexternal(name, args, result, compilation_info=eci,
-                           calling_conv=calling_conv)
+                           calling_conv=calling_conv, **kwds)
 
 def external_c(name, args, result, **kwargs):
     return rffi.llexternal(name, args, result, compilation_info=eci,
@@ -476,9 +476,9 @@
 socket = external('socket', [rffi.INT, rffi.INT, rffi.INT], socketfd_type)
 
 if WIN32:
-    socketclose = external('closesocket', [socketfd_type], rffi.INT)
+    socketclose = external('closesocket', [socketfd_type], rffi.INT, threadsafe=False)
 else:
-    socketclose = external('close', [socketfd_type], rffi.INT)
+    socketclose = external('close', [socketfd_type], rffi.INT, threadsafe=False)
 
 socketconnect = external('connect', [socketfd_type, sockaddr_ptr, socklen_t], rffi.INT)
 
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -157,7 +157,7 @@
 
 def we_are_translated():
     return False
-# annotation -> True
+# annotation -> True (replaced by the flow objspace)
 
 def keepalive_until_here(*values):
     pass
diff --git a/pypy/rlib/rdynload.py b/pypy/rlib/rdynload.py
--- a/pypy/rlib/rdynload.py
+++ b/pypy/rlib/rdynload.py
@@ -63,7 +63,7 @@
 
 if not _WIN32:
     c_dlopen = external('dlopen', [rffi.CCHARP, rffi.INT], rffi.VOIDP)
-    c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT)
+    c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT, threadsafe=False)
     c_dlerror = external('dlerror', [], rffi.CCHARP)
     c_dlsym = external('dlsym', [rffi.VOIDP, rffi.CCHARP], rffi.VOIDP)
 
diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -118,7 +118,7 @@
     has_mremap = cConfig['has_mremap']
     c_mmap, c_mmap_safe = external('mmap', [PTR, size_t, rffi.INT, rffi.INT,
                                rffi.INT, off_t], PTR)
-    c_munmap, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT)
+    _, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT)
     c_msync, _ = external('msync', [PTR, size_t, rffi.INT], rffi.INT)
     if has_mremap:
         c_mremap, _ = external('mremap',
@@ -174,7 +174,8 @@
     DuplicateHandle = winexternal('DuplicateHandle', [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD], BOOL)
     CreateFileMapping = winexternal('CreateFileMappingA', [HANDLE, rwin32.LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR], HANDLE)
     MapViewOfFile = winexternal('MapViewOfFile', [HANDLE, DWORD, DWORD, DWORD, SIZE_T], LPCSTR)##!!LPVOID)
-    UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCVOID], BOOL)
+    UnmapViewOfFile = winexternal('UnmapViewOfFile', [LPCVOID], BOOL,
+                                  threadsafe=False)
     FlushViewOfFile = winexternal('FlushViewOfFile', [LPCVOID, SIZE_T], BOOL)
     SetFilePointer = winexternal('SetFilePointer', [HANDLE, LONG, PLONG, DWORD], DWORD)
     SetEndOfFile = winexternal('SetEndOfFile', [HANDLE], BOOL)
@@ -294,7 +295,7 @@
                 os.close(self.fd)
                 self.fd = -1
             if self.size > 0:
-                c_munmap(self.getptr(0), self.size)
+                c_munmap_safe(self.getptr(0), self.size)
                 self.setdata(NODATA, 0)
 
     def __del__(self):
diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py
--- a/pypy/rlib/ropenssl.py
+++ b/pypy/rlib/ropenssl.py
@@ -273,7 +273,7 @@
 EVP_MD_CTX_copy = external(
     'EVP_MD_CTX_copy', [EVP_MD_CTX, EVP_MD_CTX], rffi.INT)
 EVP_MD_CTX_cleanup = external(
-    'EVP_MD_CTX_cleanup', [EVP_MD_CTX], rffi.INT)
+    'EVP_MD_CTX_cleanup', [EVP_MD_CTX], rffi.INT, threadsafe=False)
 
 def init_ssl():
     libssl_SSL_load_error_strings()
diff --git a/pypy/rlib/rwin32.py b/pypy/rlib/rwin32.py
--- a/pypy/rlib/rwin32.py
+++ b/pypy/rlib/rwin32.py
@@ -79,8 +79,9 @@
 for k, v in rffi_platform.configure(CConfig).items():
     globals()[k] = v
 
-def winexternal(name, args, result):
-    return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win')
+def winexternal(name, args, result, **kwds):
+    return rffi.llexternal(name, args, result, compilation_info=eci,
+                           calling_conv='win', **kwds)
 
 if WIN32:
     HANDLE = rffi.COpaquePtr(typedef='HANDLE')
@@ -92,7 +93,7 @@
     INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1)
     PFILETIME = rffi.CArrayPtr(FILETIME)
 
-    GetLastError = winexternal('GetLastError', [], DWORD)
+    GetLastError = winexternal('GetLastError', [], DWORD, threadsafe=False)
     SetLastError = winexternal('SetLastError', [DWORD], lltype.Void)
 
     # In tests, the first call to GetLastError is always wrong, because error
@@ -103,10 +104,10 @@
     GetProcAddress = winexternal('GetProcAddress',
                                  [HMODULE, rffi.CCHARP],
                                  rffi.VOIDP)
-    FreeLibrary = winexternal('FreeLibrary', [HMODULE], BOOL)
+    FreeLibrary = winexternal('FreeLibrary', [HMODULE], BOOL, threadsafe=False)
 
     LocalFree = winexternal('LocalFree', [HLOCAL], DWORD)
-    CloseHandle = winexternal('CloseHandle', [HANDLE], BOOL)
+    CloseHandle = winexternal('CloseHandle', [HANDLE], BOOL, threadsafe=False)
 
     FormatMessage = winexternal(
         'FormatMessageA',
diff --git a/pypy/rlib/rzlib.py b/pypy/rlib/rzlib.py
--- a/pypy/rlib/rzlib.py
+++ b/pypy/rlib/rzlib.py
@@ -131,7 +131,8 @@
     rffi.INT)
 _deflate = zlib_external('deflate', [z_stream_p, rffi.INT], rffi.INT)
 
-_deflateEnd = zlib_external('deflateEnd', [z_stream_p], rffi.INT)
+_deflateEnd = zlib_external('deflateEnd', [z_stream_p], rffi.INT,
+                            threadsafe=False)
 
 def _deflateInit2(stream, level, method, wbits, memlevel, strategy):
     size = rffi.sizeof(z_stream)
@@ -149,7 +150,8 @@
     rffi.INT)
 _inflate = zlib_external('inflate', [z_stream_p, rffi.INT], rffi.INT)
 
-_inflateEnd = zlib_external('inflateEnd', [z_stream_p], rffi.INT)
+_inflateEnd = zlib_external('inflateEnd', [z_stream_p], rffi.INT,
+                            threadsafe=False)
 
 def _inflateInit2(stream, wbits):
     size = rffi.sizeof(z_stream)
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -877,7 +877,8 @@
 
     @registering(os.close)
     def register_os_close(self):
-        os_close = self.llexternal(underscore_on_windows+'close', [rffi.INT], rffi.INT)
+        os_close = self.llexternal(underscore_on_windows+'close', [rffi.INT],
+                                   rffi.INT, threadsafe=False)
         
         def close_llimpl(fd):
             error = rffi.cast(lltype.Signed, os_close(rffi.cast(rffi.INT, fd)))
diff --git a/pypy/rpython/module/ll_os_stat.py b/pypy/rpython/module/ll_os_stat.py
--- a/pypy/rpython/module/ll_os_stat.py
+++ b/pypy/rpython/module/ll_os_stat.py
@@ -21,7 +21,7 @@
 #   sub-second timestamps.
 # - TIMESPEC is defined when the "struct stat" contains st_atim field.
 
-if sys.platform.startswith('linux'):
+if sys.platform.startswith('linux') or sys.platform.startswith('openbsd'):
     TIMESPEC = platform.Struct('struct timespec',
                                [('tv_sec', rffi.TIME_T),
                                 ('tv_nsec', rffi.LONG)])
@@ -185,9 +185,9 @@
 def build_stat_result(st):
     # only for LL backends
     if TIMESPEC is not None:
-        atim = st.c_st_atim; atime = atim.c_tv_sec + 1E-9 * atim.c_tv_nsec
-        mtim = st.c_st_mtim; mtime = mtim.c_tv_sec + 1E-9 * mtim.c_tv_nsec
-        ctim = st.c_st_ctim; ctime = ctim.c_tv_sec + 1E-9 * ctim.c_tv_nsec
+        atim = st.c_st_atim; atime = int(atim.c_tv_sec) + 1E-9 * int(atim.c_tv_nsec)
+        mtim = st.c_st_mtim; mtime = int(mtim.c_tv_sec) + 1E-9 * int(mtim.c_tv_nsec)
+        ctim = st.c_st_ctim; ctime = int(ctim.c_tv_sec) + 1E-9 * int(ctim.c_tv_nsec)
     else:
         atime = st.c_st_atime
         mtime = st.c_st_mtime
diff --git a/pypy/rpython/raddress.py b/pypy/rpython/raddress.py
--- a/pypy/rpython/raddress.py
+++ b/pypy/rpython/raddress.py
@@ -7,7 +7,6 @@
 from pypy.rpython.rptr import PtrRepr
 from pypy.rpython.lltypesystem import lltype
 from pypy.rlib.rarithmetic import r_uint
-from pypy.rlib.objectmodel import we_are_translated
 
 
 class __extend__(annmodel.SomeAddress):
diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py
--- a/pypy/rpython/rbuiltin.py
+++ b/pypy/rpython/rbuiltin.py
@@ -283,10 +283,6 @@
         v_error = hop.inputarg(lltype.Signed, arg=1)
         r_self.setfield(v_self, 'winerror', v_error, hop.llops)
 
-def rtype_we_are_translated(hop):
-    hop.exception_cannot_occur()
-    return hop.inputconst(lltype.Bool, True)
-
 def rtype_hlinvoke(hop):
     _, s_repr = hop.r_s_popfirstarg()
     r_callable = s_repr.const
@@ -553,7 +549,6 @@
 BUILTIN_TYPER[lltype.Ptr] = rtype_const_result
 BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info
 BUILTIN_TYPER[rarithmetic.intmask] = rtype_intmask
-BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated
 
 BUILTIN_TYPER[objectmodel.hlinvoke] = rtype_hlinvoke
 
diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py
--- a/pypy/rpython/tool/rffi_platform.py
+++ b/pypy/rpython/tool/rffi_platform.py
@@ -11,6 +11,7 @@
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.platform import CompilationError
 from pypy.tool.udir import udir
+from pypy.tool.autopath import pypydir
 from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask
 
 # ____________________________________________________________
@@ -699,6 +700,13 @@
 
 # ____________________________________________________________
 
+PYPY_EXTERNAL_DIR = py.path.local(pypydir).join('..', '..')
+# XXX make this configurable
+if sys.platform == 'win32':
+    libdir = py.path.local('c:/buildslave/support') # on the bigboard buildbot
+    if libdir.check():
+        PYPY_EXTERNAL_DIR = libdir
+
 def configure_external_library(name, eci, configurations,
                                symbol=None, _cache={}):
     """try to find the external library.
@@ -740,11 +748,7 @@
             if prefix and not os.path.isabs(prefix):
                 import glob
 
-                # XXX make this a global option?
-                from pypy.tool.autopath import pypydir
-                external_dir = py.path.local(pypydir).join('..', '..')
-
-                entries = glob.glob(str(external_dir.join(prefix + '*')))
+                entries = glob.glob(str(PYPY_EXTERNAL_DIR.join(prefix + '*')))
                 if entries:
                     # Get last version
                     prefix = sorted(entries)[-1]
@@ -780,14 +784,16 @@
         from pypy.translator.platform import platform
     if sys.platform == 'win32':
         library_dir = 'Release'
+        libraries = ['gc']
         includes=['gc.h']
     else:
         library_dir = ''
+        libraries = ['gc', 'dl']
         includes=['gc/gc.h']
     eci = ExternalCompilationInfo(
         platform=platform,
         includes=includes,
-        libraries=['gc', 'dl'],
+        libraries=libraries,
         )
     return configure_external_library(
         'gc', eci,
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -229,7 +229,7 @@
         if sys.platform.startswith('linux'):
             pre_include_bits += ["#define _REENTRANT 1",
                                  "#define GC_LINUX_THREADS 1"]
-        if sys.platform != "win32":
+        if sys.platform != "win32" and not sys.platform.startswith("openbsd"):
             # GC_REDIRECT_TO_LOCAL is not supported on Win32 by gc6.8
             pre_include_bits += ["#define GC_REDIRECT_TO_LOCAL 1"]
 
diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -422,8 +422,11 @@
     # (relevant in case of "reload(sys)")
     sys.argv[:] = argv
 
-    if (PYTHON26 and not options["ignore_environment"] and os.getenv('PYTHONNOUSERSITE')):
-        options["no_user_site"] = True
+    if PYTHON26 and not options["ignore_environment"]:
+        if os.getenv('PYTHONNOUSERSITE'):
+            options["no_user_site"] = True
+        if os.getenv('PYTHONDONTWRITEBYTECODE'):
+            options["dont_write_bytecode"] = True
 
     if (options["interactive"] or
         (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))):
@@ -432,7 +435,8 @@
     if PYTHON26 and we_are_translated():
         flags = [options[flag] for flag in sys_flags]
         sys.flags = type(sys.flags)(flags)
-        sys.py3kwarning = sys.flags.py3k_warning
+        sys.py3kwarning = bool(sys.flags.py3k_warning)
+        sys.dont_write_bytecode = bool(sys.flags.dont_write_bytecode)
 
         if sys.py3kwarning:
             print >> sys.stderr, (
diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py
--- a/pypy/translator/platform/__init__.py
+++ b/pypy/translator/platform/__init__.py
@@ -252,6 +252,13 @@
         host_factory = Freebsd
     else:
         host_factory = Freebsd_64
+elif "openbsd" in sys.platform:
+    from pypy.translator.platform.openbsd import OpenBSD, OpenBSD_64
+    import platform
+    if platform.architecture()[0] == '32bit':
+        host_factory = OpenBSD
+    else:
+        host_factory = OpenBSD_64
 elif os.name == 'nt':
     from pypy.translator.platform.windows import Windows
     host_factory = Windows
diff --git a/pypy/translator/platform/openbsd.py b/pypy/translator/platform/openbsd.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/platform/openbsd.py
@@ -0,0 +1,61 @@
+"""Support for OpenBSD."""
+
+import os
+
+from pypy.translator.platform import posix
+
+def get_env(key, default):
+    if key in os.environ:
+        return os.environ[key]
+    else:
+        return default
+
+def get_env_vector(key, default):
+    string = get_env(key, default)
+    # XXX: handle quotes
+    return string.split()
+
+class OpenBSD(posix.BasePosix):
+    name = "openbsd"
+
+    link_flags = get_env_vector("LDFLAGS", '-pthread')
+    cflags = get_env_vector("CFLAGS", "-O3 -pthread -fomit-frame-pointer -D_BSD_SOURCE")
+    standalone_only = []
+    shared_only = []
+    so_ext = 'so'
+    make_cmd = 'gmake'
+
+    def __init__(self, cc=None):
+        if cc is None:
+            cc = get_env("CC", "gcc")
+        super(OpenBSD, self).__init__(cc)
+
+    def _args_for_shared(self, args):
+        return ['-shared'] + args
+
+    def _preprocess_include_dirs(self, include_dirs):
+        res_incl_dirs = list(include_dirs)
+        res_incl_dirs.append(os.path.join(get_env("LOCALBASE", "/usr/local"), "include"))
+        return res_incl_dirs
+
+    def _preprocess_library_dirs(self, library_dirs):
+        res_lib_dirs = list(library_dirs)
+        res_lib_dirs.append(os.path.join(get_env("LOCALBASE", "/usr/local"), "lib"))
+        return res_lib_dirs
+
+    def _include_dirs_for_libffi(self):
+        return [os.path.join(get_env("LOCALBASE", "/usr/local"), "include")]
+
+    def _library_dirs_for_libffi(self):
+        return [os.path.join(get_env("LOCALBASE", "/usr/local"), "lib")]
+
+    def _libs(self, libraries):
+        libraries=set(libraries + ("intl", "iconv", "compat"))
+        return ['-l%s' % lib for lib in libraries if lib not in ["crypt", "dl", "rt"]]
+
+    def check___thread(self):
+        # currently __thread is not supported by Darwin gccs
+        return False
+
+class OpenBSD_64(OpenBSD):
+    shared_only = ('-fPIC',)


More information about the pypy-commit mailing list