Author: Amaury Forgeot d'Arc <[email protected]>
Branch: more-rposix
Changeset: r74338:e2c7497831fa
Date: 2014-11-04 20:59 +0100
http://bitbucket.org/pypy/pypy/changeset/e2c7497831fa/

Log:    Start moving functions: os.dup, os.dup2

diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -286,6 +286,17 @@
     return Constant(True)
 
 
+def register_replacement_for(replaced_function):
+    """Decorator that causes RPython to replace the function passed as 
parameter
+    with the function being defined."""
+    def wrap(func):
+        @register_flow_sc(replaced_function)
+        def sc_redirected_function(ctx, *args_w):
+            return ctx.appcall(func, *args_w)
+        return func
+    return wrap
+
+
 def keepalive_until_here(*values):
     pass
 
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1,12 +1,15 @@
 import os
+import sys
 from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT
 from rpython.rtyper.lltypesystem import ll2ctypes, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.rlib.rarithmetic import intmask
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, register_replacement_for
 from rpython.rlib import jit
 from rpython.translator.platform import platform
 
+_WIN32 = sys.platform.startswith('win')
+UNDERSCORE_ON_WIN32 = '_' if _WIN32 else ''
 
 class CConstantErrno(CConstant):
     # these accessors are used when calling get_errno() or set_errno()
@@ -127,6 +130,20 @@
         except OSError:
             pass
 
+if _WIN32:
+    includes = ['io.h']
+else:
+    includes = ['unistd.h']
+eci = ExternalCompilationInfo(
+    includes=includes,
+)
+
+def external(name, args, result, **kwds):
+    return rffi.llexternal(name, args, result, compilation_info=eci, **kwds)
+
+c_dup = external(UNDERSCORE_ON_WIN32 + 'dup', [rffi.INT], rffi.INT)
+c_dup2 = external(UNDERSCORE_ON_WIN32 + 'dup2', [rffi.INT, rffi.INT], rffi.INT)
+
 #___________________________________________________________________
 # Wrappers around posix functions, that accept either strings, or
 # instances with a "as_bytes()" method.
@@ -227,3 +244,23 @@
     os_kill = rwin32.os_kill
 else:
     os_kill = os.kill
+
+#___________________________________________________________________
+# Implementation of many posix functions.
+# They usually check the return value and raise an (RPython) OSError
+# with errno.
+
+@register_replacement_for(os.dup)
+def dup(fd):
+    validate_fd(fd)
+    newfd = c_dup(fd)
+    if newfd < 0:
+        raise OSError(get_errno(), "dup failed")
+    return newfd
+
+@register_replacement_for(os.dup2)
+def dup2(fd, newfd):
+    validate_fd(fd)
+    error = c_dup2(fd, newfd)
+    if error < 0:
+        raise OSError(get_errno(), "dup2 failed")
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -169,3 +169,10 @@
     def _get_filename(self):
         return (unicode(udir.join('test_open')) +
                 u'\u65e5\u672c.txt') # "Japan"
+
+class TestRegisteredFunctions:
+    def test_dup(self):
+        def f():
+            os.dup(4)
+            os.dup2(5, 6)
+        compile(f, ())
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -346,35 +346,6 @@
                       llimpl=spawnve_llimpl,
                       export_name="ll_os.ll_os_spawnve")
 
-    @registering(os.dup)
-    def register_os_dup(self):
-        os_dup = self.llexternal(UNDERSCORE_ON_WIN32 + 'dup',
-                                 [rffi.INT], rffi.INT)
-
-        def dup_llimpl(fd):
-            rposix.validate_fd(fd)
-            newfd = rffi.cast(lltype.Signed, os_dup(rffi.cast(rffi.INT, fd)))
-            if newfd == -1:
-                raise OSError(rposix.get_errno(), "dup failed")
-            return newfd
-
-        return extdef([int], int, llimpl=dup_llimpl, 
export_name="ll_os.ll_os_dup")
-
-    @registering(os.dup2)
-    def register_os_dup2(self):
-        os_dup2 = self.llexternal(UNDERSCORE_ON_WIN32 + 'dup2',
-                                  [rffi.INT, rffi.INT], rffi.INT)
-
-        def dup2_llimpl(fd, newfd):
-            rposix.validate_fd(fd)
-            error = rffi.cast(lltype.Signed, os_dup2(rffi.cast(rffi.INT, fd),
-                                             rffi.cast(rffi.INT, newfd)))
-            if error == -1:
-                raise OSError(rposix.get_errno(), "dup2 failed")
-
-        return extdef([int, int], s_None, llimpl=dup2_llimpl,
-                      export_name="ll_os.ll_os_dup2")
-
     @registering_if(os, "getlogin", condition=not _WIN32)
     def register_os_getlogin(self):
         os_getlogin = self.llexternal('getlogin', [], rffi.CCHARP, 
releasegil=False)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to