[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