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