[pypy-svn] r14469 - in pypy/dist/pypy: rpython rpython/module rpython/module/test translator/c

arigo at codespeak.net arigo at codespeak.net
Sun Jul 10 13:49:58 CEST 2005


Author: arigo
Date: Sun Jul 10 13:49:53 2005
New Revision: 14469

Added:
   pypy/dist/pypy/rpython/module/   (props changed)
   pypy/dist/pypy/rpython/module/__init__.py   (contents, props changed)
   pypy/dist/pypy/rpython/module/ll_os.py   (contents, props changed)
   pypy/dist/pypy/rpython/module/ll_time.py   (contents, props changed)
   pypy/dist/pypy/rpython/module/test/   (props changed)
   pypy/dist/pypy/rpython/module/test/__init__.py   (contents, props changed)
   pypy/dist/pypy/rpython/module/test/test_ll_os.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/extfunctable.py
   pypy/dist/pypy/translator/c/fixedname.py
   pypy/dist/pypy/translator/c/node.py
Log:
Trying to write a bit more for ll_os_read(), I ran into circular import
problems which have prompted this refactoring (which would have been done soon
anyway): the ll_xxx() functions are grouped by module, in a 'rpython/module/'
subdirectory.  The extfunctable imports these modules lazily.


Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py	(original)
+++ pypy/dist/pypy/rpython/extfunctable.py	Sun Jul 10 13:49:53 2005
@@ -5,14 +5,35 @@
 import time
 import types
 
+
 class ExtFuncInfo:
-    def __init__(self, func, annotation, ll_function, ll_annotable, backend_functiontemplate):
+    def __init__(self, func, annotation, ll_function_path, ll_annotable, backend_functiontemplate):
         self.func = func
         self.annotation = annotation
-        self.ll_function = ll_function
+        modulename, ignored = ll_function_path.split('/')
+        self.ll_module = ImportMe('pypy.rpython.module.%s' % modulename)
+        self.ll_function_name = ll_function_path.replace('/', '_')
         self.ll_annotable = ll_annotable
         self.backend_functiontemplate = backend_functiontemplate
 
+    def get_ll_function(self):
+        """Get the ll_*() function implementing the given high-level 'func'."""
+        mod = self.ll_module.load()
+        return getattr(mod, self.ll_function_name)
+    ll_function = property(get_ll_function)
+
+
+class ImportMe:
+    "Lazily imported module, for circular imports :-/"
+    def __init__(self, modulename):
+        self.modulename = modulename
+        self._mod = None
+    def load(self):
+        if self._mod is None:
+            self._mod = __import__(self.modulename, None, None, ['__doc__'])
+        return self._mod
+
+
 table = {}
 def declare(func, annotation, ll_function, ll_annotable=False, backend_functiontemplate=None):
     # annotation can be a function computing the annotation
@@ -25,56 +46,17 @@
             return bookkeeper.getbookkeeper().valueoftype(typ)
     table[func] = ExtFuncInfo(func, annotation, ll_function, ll_annotable, backend_functiontemplate)
 
-# utility conversion functions
-def to_rstr(s):
-    from pypy.rpython import rstr
-    p = rstr.malloc(rstr.STR, len(s))
-    for i in range(len(s)):
-        p.chars[i] = s[i]
-    return p
-
-def from_rstr(rs):
-    return ''.join([rs.chars[i] for i in range(len(rs.chars))])
-
-# dummy low-level implementations for the external functions
-def ll_os_open(fname, flag, mode):
-    return os.open(from_rstr(fname), flag, mode)
-ll_os_open.suggested_primitive=True
-
-def ll_os_read(fd, n):
-    return to_rstr(os.read(fd, n))
-    
-def ll_os_write(fd, astring):
-    return os.write(fd, from_rstr(astring))
-
-def ll_os_close(fd):
-    os.close(fd)
-    
-def ll_os_getcwd():
-    return to_rstr(os.getcwd())
-
-def ll_os_dup(fd):
-    return os.dup(fd)
-
-def ll_time_time():
-    return time.time()
-
-def ll_time_clock():
-    return time.clock()
-
-def ll_time_sleep(t):
-    time.sleep(t)
-
+# _____________________________________________________________
 
 nonefactory = lambda *args: None
 
 # external function declarations
-declare(os.open   , int        , ll_os_open, True)
-declare(os.read   , str        , ll_os_read)
-declare(os.write  , int        , ll_os_write)
-declare(os.close  , nonefactory, ll_os_close)
-declare(os.getcwd , str        , ll_os_getcwd)
-declare(os.dup    , int        , ll_os_dup)
-declare(time.time , float      , ll_time_time)
-declare(time.clock, float      , ll_time_clock)
-declare(time.sleep, nonefactory, ll_time_sleep)
+declare(os.open   , int        , 'll_os/open', True)
+declare(os.read   , str        , 'll_os/read')
+declare(os.write  , int        , 'll_os/write')
+declare(os.close  , nonefactory, 'll_os/close')
+declare(os.getcwd , str        , 'll_os/getcwd')
+declare(os.dup    , int        , 'll_os/dup')
+declare(time.time , float      , 'll_time/time')
+declare(time.clock, float      , 'll_time/clock')
+declare(time.sleep, nonefactory, 'll_time/sleep')

Added: pypy/dist/pypy/rpython/module/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/module/__init__.py	Sun Jul 10 13:49:53 2005
@@ -0,0 +1 @@
+#

Added: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/module/ll_os.py	Sun Jul 10 13:49:53 2005
@@ -0,0 +1,79 @@
+"""
+Dummy low-level implementations for the external functions of the 'os' module.
+"""
+
+# Idea: each ll_os_xxx() function calls back the os.xxx() function that it
+# is supposed to implement, either directly or indirectly if there is some
+# argument decoding and buffering preparation that can be done here.
+
+# The specific function that calls back to os.xxx() is tagged with the
+# 'suggested_primitive' flag.  The back-end should special-case it and really
+# implement it.  The back-end can actually choose to special-case any function:
+# it can for example special-case ll_os_xxx() directly even if the
+# 'suggested_primitive' flag is set to another function, if the conversion
+# and buffer preparation stuff is not useful.
+
+import os, errno
+from pypy.rpython.rstr import STR
+from pypy.rpython.lltype import malloc
+
+
+# utility conversion functions
+def to_rstr(s):
+    p = malloc(STR, len(s))
+    for i in range(len(s)):
+        p.chars[i] = s[i]
+    return p
+
+def from_rstr(rs):
+    return ''.join([rs.chars[i] for i in range(len(rs.chars))])
+
+def ll_strcpy(dstchars, srcchars, n):
+    i = 0
+    while i < n:
+        dstchars[i] = srcchars[i]
+        i += 1
+
+# ____________________________________________________________
+
+def ll_os_open(fname, flag, mode):
+    return os.open(from_rstr(fname), flag, mode)
+ll_os_open.suggested_primitive = True
+
+
+def ll_read_into(fd, buffer):
+    data = os.read(fd, len(buffer.chars))
+    ll_strcpy(buffer.chars, data, len(data))
+    return len(data)
+ll_read_into.suggested_primitive = True
+
+def ll_os_read(fd, count):
+    if count < 0:
+        raise OSError(errno.EINVAL, None)
+    buffer = malloc(STR, count)
+    n = ll_read_into(fd, buffer)
+    if n != count:
+        s = malloc(STR, n)
+        ll_strcpy(s.chars, buffer.chars, n)
+        buffer = s
+    return buffer
+
+
+def ll_os_write(fd, astring):
+    return os.write(fd, from_rstr(astring))
+ll_os_write.suggested_primitive = True
+
+
+def ll_os_close(fd):
+    os.close(fd)
+ll_os_close.suggested_primitive = True
+
+
+def ll_os_getcwd():
+    return to_rstr(os.getcwd())
+ll_os_getcwd.suggested_primitive = True
+
+
+def ll_os_dup(fd):
+    return os.dup(fd)
+ll_os_dup.suggested_primitive = True

Added: pypy/dist/pypy/rpython/module/ll_time.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/module/ll_time.py	Sun Jul 10 13:49:53 2005
@@ -0,0 +1,20 @@
+"""
+Dummy low-level implementations for the external functions of the 'time' module.
+"""
+
+# See ll_os.py.
+
+import time
+
+
+def ll_time_time():
+    return time.time()
+ll_time_time.suggested_primitive = True
+
+def ll_time_clock():
+    return time.clock()
+ll_time_clock.suggested_primitive = True
+
+def ll_time_sleep(t):
+    time.sleep(t)
+ll_time_sleep.suggested_primitive = True

Added: pypy/dist/pypy/rpython/module/test/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/module/test/__init__.py	Sun Jul 10 13:49:53 2005
@@ -0,0 +1 @@
+#

Added: pypy/dist/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os.py	Sun Jul 10 13:49:53 2005
@@ -0,0 +1,25 @@
+import os
+from pypy.tool.udir import udir
+from pypy.rpython.module.ll_os import *
+
+
+def test_open_read_write_close():
+    filename = str(udir.join('test_open_read_write_close.txt'))
+    rsfilename = to_rstr(filename)
+
+    fd = ll_os_open(rsfilename, os.O_WRONLY | os.O_CREAT, 0777)
+    count = ll_os_write(fd, to_rstr("hello world\n"))
+    assert count == len("hello world\n")
+    ll_os_close(fd)
+
+    fd = ll_os_open(rsfilename, os.O_RDONLY, 0777)
+    data = ll_os_read(fd, 500)
+    assert from_rstr(data) == "hello world\n"
+    ll_os_close(fd)
+
+    os.unlink(filename)
+
+
+def test_getcwd():
+    data = ll_os_getcwd()
+    assert from_rstr(data) == os.getcwd()

Modified: pypy/dist/pypy/translator/c/fixedname.py
==============================================================================
--- pypy/dist/pypy/translator/c/fixedname.py	(original)
+++ pypy/dist/pypy/translator/c/fixedname.py	Sun Jul 10 13:49:53 2005
@@ -3,13 +3,13 @@
 from pypy.translator.c.support import cdecl
 from pypy.rpython.rmodel import getfunctionptr
 from pypy.rpython.rstr import STR
-from pypy.rpython import extfunctable
+from pypy.rpython.module import ll_os, ll_time
 
 
 # table of functions hand-written in extfunc_include.h
 EXTERNALS = {
-    extfunctable.ll_os_open:    'LL_os_open',
-    extfunctable.ll_time_clock: 'LL_time_clock',
+    ll_os  .ll_os_open:    'LL_os_open',
+    ll_time.ll_time_clock: 'LL_time_clock',
     }
 
 

Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Sun Jul 10 13:49:53 2005
@@ -474,9 +474,10 @@
 
 def select_function_code_generator(fnobj, db):
     if fnobj._callable in fixedname.EXTERNALS:
-        # 'fnobj' is one of the ll_xyz() functions special-cased in
-        # pypy.rpython.extfunctable.  The corresponding C wrappers are written
-        # by hand in extfunc_include.h, and declared in fixedname.EXTERNALS.
+        # 'fnobj' is one of the ll_xyz() functions with the suggested_primitive
+        # flag in pypy.rpython.module.*.  The corresponding C wrappers are
+        # written by hand in extfunc_include.h, and declared in
+        # fixedname.EXTERNALS.
         db.externalfuncs[fnobj._callable] = fnobj
         return None
     elif hasattr(fnobj, 'graph'):



More information about the Pypy-commit mailing list