[pypy-svn] r14474 - in pypy/dist/pypy: annotation rpython rpython/test translator/c translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Sun Jul 10 15:27:45 CEST 2005
Author: arigo
Date: Sun Jul 10 15:27:40 2005
New Revision: 14474
Modified:
pypy/dist/pypy/annotation/specialize.py
pypy/dist/pypy/rpython/annlowlevel.py
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/rmodel.py
pypy/dist/pypy/rpython/rtyper.py
pypy/dist/pypy/rpython/test/test_rbuiltin.py
pypy/dist/pypy/translator/c/extfunc_include.h
pypy/dist/pypy/translator/c/fixedname.py
pypy/dist/pypy/translator/c/node.py
pypy/dist/pypy/translator/c/test/test_extfunc.py
Log:
GenC now passes a test for os.open/write/read/close(). This required the
following changes:
- some C code in extfunc_include.h, but not too much. It looks quite nice.
- specialization now always attached an attribute _specializedversionof_ to
the specialized functions, pointing back to the original one. This allows
the function pointer objects to have the original function as _callable
in all cases, which is needed to be able to recognize them.
- all ll_os_* and ll_time_* functions are now annotated by default. This
required some more allowance in annlowlevel to not complain on high-level
objects (e.g. SomeStrings) being passed around in low-level functions.
- fix some broken tests.
- GenC checks that it isn't trying to compile a suggested_primitive.
Modified: pypy/dist/pypy/annotation/specialize.py
==============================================================================
--- pypy/dist/pypy/annotation/specialize.py (original)
+++ pypy/dist/pypy/annotation/specialize.py Sun Jul 10 15:27:40 2005
@@ -27,7 +27,7 @@
if isinstance(key, tuple):
# cache specialization
try:
- func = bookkeeper.cachespecializations[key]
+ newfunc = bookkeeper.cachespecializations[key]
except KeyError:
if key[0] is func:
postfix = key[1:]
@@ -36,14 +36,16 @@
newfunc = clone(func, postfix)
if key[0] is func:
bookkeeper.cachespecializations[(newfunc,) + postfix] = newfunc
- func = bookkeeper.cachespecializations[key] = newfunc
+ bookkeeper.cachespecializations[key] = newfunc
elif isinstance(key, str):
# specialization explicit in operation annotation
postfix = key
- func = clone(func, postfix)
+ newfunc = clone(func, postfix)
else:
# specialization already retrieved
- func = key
+ newfunc = key
+ newfunc._specializedversionof_ = func
+ func = newfunc
if unpacked:
func = func, args
Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py (original)
+++ pypy/dist/pypy/rpython/annlowlevel.py Sun Jul 10 15:27:40 2005
@@ -45,7 +45,12 @@
new_args_s.append(s_obj)
else:
new_args_s.append(not_const(s_obj))
- key.append(annmodel.annotation_to_lltype(s_obj))
+ try:
+ key.append(annmodel.annotation_to_lltype(s_obj))
+ except ValueError:
+ # passing non-low-level types to a ll_* function is allowed
+ # for module/ll_*
+ key.append(s_obj.__class__)
return tuple(key), bookkeeper.build_args('simple_call', new_args_s)
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Sun Jul 10 15:27:40 2005
@@ -35,7 +35,7 @@
table = {}
-def declare(func, annotation, ll_function, ll_annotable=False, backend_functiontemplate=None):
+def declare(func, annotation, ll_function, ll_annotable=True, backend_functiontemplate=None):
# annotation can be a function computing the annotation
# or a simple python type from which an annotation will be constructed
global table
@@ -51,7 +51,7 @@
nonefactory = lambda *args: None
# external function declarations
-declare(os.open , int , 'll_os/open', True)
+declare(os.open , int , 'll_os/open')
declare(os.read , str , 'll_os/read')
declare(os.write , int , 'll_os/write')
declare(os.close , nonefactory, 'll_os/close')
Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py (original)
+++ pypy/dist/pypy/rpython/rmodel.py Sun Jul 10 15:27:40 2005
@@ -226,13 +226,12 @@
def getconcretetype(v):
return getattr(v, 'concretetype', PyObjPtr)
-def getfunctionptr(translator, graphfunc, getconcretetype=getconcretetype, _callable=None):
+def getfunctionptr(translator, graphfunc, getconcretetype=getconcretetype):
"""Make a functionptr from the given Python function."""
graph = translator.getflowgraph(graphfunc)
llinputs = [getconcretetype(v) for v in graph.getargs()]
lloutput = getconcretetype(graph.getreturnvar())
FT = FuncType(llinputs, lloutput)
- if _callable is None:
- _callable = graphfunc
+ _callable = getattr(graphfunc, '_specializedversionof_', graphfunc)
return functionptr(FT, graphfunc.func_name, graph = graph, _callable = _callable)
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Sun Jul 10 15:27:40 2005
@@ -382,10 +382,10 @@
# __________ utilities __________
- def getfunctionptr(self, graphfunc, _callable=None):
+ def getfunctionptr(self, graphfunc):
def getconcretetype(v):
return self.bindingrepr(v).lowleveltype
- return getfunctionptr(self.annotator.translator, graphfunc, getconcretetype, _callable=_callable)
+ return getfunctionptr(self.annotator.translator, graphfunc, getconcretetype)
def attachRuntimeTypeInfoFunc(self, GCSTRUCT, func, ARG_GCSTRUCT=None):
self.call_all_setups() # compute ForwardReferences now
@@ -543,7 +543,7 @@
dontcare, spec_function = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s)
# build the 'direct_call' operation
- f = self.rtyper.getfunctionptr(spec_function, _callable=ll_function)
+ f = self.rtyper.getfunctionptr(spec_function)
c = inputconst(typeOf(f), f)
return self.genop('direct_call', [c]+list(args_v),
resulttype = typeOf(f).TO.RESULT)
Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sun Jul 10 15:27:40 2005
@@ -93,10 +93,10 @@
except OSError:
pass
count = 0
- from pypy.rpython import extfunctable
+ from pypy.rpython.module import ll_os
for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, fn):
cfptr = dir_call.args[0]
- assert cfptr.value._obj._callable == extfunctable.ll_os_dup
+ assert cfptr.value._obj._callable == ll_os.ll_os_dup
count += 1
assert count == 1
@@ -110,10 +110,10 @@
res = interpret(f, [])
os.close(res)
count = 0
- from pypy.rpython import extfunctable
+ from pypy.rpython.module import ll_os
for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open):
cfptr = dir_call.args[0]
- assert cfptr.value._obj._callable == extfunctable.ll_os_open
+ assert cfptr.value._obj._callable == ll_os.ll_os_open
count += 1
assert count == 1
Modified: pypy/dist/pypy/translator/c/extfunc_include.h
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc_include.h (original)
+++ pypy/dist/pypy/translator/c/extfunc_include.h Sun Jul 10 15:27:40 2005
@@ -6,6 +6,7 @@
/******************************************************************/
+#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -15,32 +16,66 @@
#define PATH_MAX 254
#endif
-/* The functions below are mapped to functions from pypy.rpython.extfunctable
- by the pypy.translator.c.fixedname.EXTERNALS dictionary. */
+/* The functions below are mapped to functions from pypy.rpython.module.*
+ by the pypy.translator.c.fixedname.EXTERNALS dictionary.
+ They should correspond to the functions with the suggested_primitive
+ flag set, and NOT necessarily directly to the ll_os_*() functions.
+ See for example ll_read_into(), which is called by ll_os_read().
+ The latter would be messy to write here, but LL_read_into() is quite easy.
+*/
#define RPyString_Size(rps) ((rps)->rs_chars.length)
#define RPyString_AsString(rps) ((rps)->rs_chars.items)
+/************************************************************/
+ /*** os module ***/
+
+
int LL_os_open(RPyString *filename, int flag, int mode)
{
char buf[PATH_MAX];
int fd, error, namelen = RPyString_Size(filename);
if (namelen >= PATH_MAX) {
- error = ENAMETOOLONG;
+ RAISE_OSERROR(ENAMETOOLONG);
+ return -1;
}
else {
memcpy(buf, RPyString_AsString(filename), namelen);
buf[namelen] = 0;
fd = open(buf, flag, mode);
- if (fd != -1)
- return fd;
- error = errno;
+ if (fd == -1)
+ RAISE_OSERROR(errno);
+ return fd;
}
- RAISE_OSERROR(error);
- return -1;
}
+long LL_read_into(int fd, RPyString *buffer)
+{
+ long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer));
+ if (n == -1)
+ RAISE_OSERROR(errno);
+ return n;
+}
+
+long LL_os_write(int fd, RPyString *buffer)
+{
+ long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer));
+ if (n == -1)
+ RAISE_OSERROR(errno);
+ return n;
+}
+
+void LL_os_close(int fd)
+{
+ if (close(fd) == -1)
+ RAISE_OSERROR(errno);
+}
+
+
+/************************************************************/
+ /*** time module ***/
+
double LL_time_clock(void)
{
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 15:27:40 2005
@@ -9,6 +9,9 @@
# table of functions hand-written in extfunc_include.h
EXTERNALS = {
ll_os .ll_os_open: 'LL_os_open',
+ ll_os .ll_read_into: 'LL_read_into',
+ ll_os .ll_os_write: 'LL_os_write',
+ ll_os .ll_os_close: 'LL_os_close',
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 15:27:40 2005
@@ -480,6 +480,9 @@
# fixedname.EXTERNALS.
db.externalfuncs[fnobj._callable] = fnobj
return None
+ elif getattr(fnobj._callable, 'suggested_primitive', False):
+ raise ValueError, "trying to compile suggested primitive %r" % (
+ fnobj._callable,)
elif hasattr(fnobj, 'graph'):
cpython_exc = getattr(fnobj, 'exception_policy', None) == "CPython"
return FunctionCodeGenerator(fnobj.graph, db, cpython_exc)
Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_extfunc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_extfunc.py Sun Jul 10 15:27:40 2005
@@ -1,11 +1,11 @@
import autopath
import py
+import os, time
from pypy.tool.udir import udir
from pypy.translator.c.test.test_genc import compile
def test_time_clock():
- import time
def does_stuff():
return time.clock()
f1 = compile(does_stuff, [])
@@ -17,7 +17,6 @@
def test_os_open():
- import os
tmpfile = str(udir.join('test_os_open.txt'))
def does_stuff():
fd = os.open(tmpfile, os.O_WRONLY | os.O_CREAT, 0777)
@@ -29,7 +28,6 @@
assert os.path.exists(tmpfile)
def test_failing_os_open():
- import os
tmpfile = str(udir.join('test_failing_os_open.DOESNTEXIST'))
def does_stuff():
fd = os.open(tmpfile, os.O_RDONLY, 0777)
@@ -38,3 +36,20 @@
f1 = compile(does_stuff, [])
py.test.raises(OSError, f1)
assert not os.path.exists(tmpfile)
+
+def test_open_read_write_close():
+ filename = str(udir.join('test_open_read_write_close.txt'))
+ def does_stuff():
+ fd = os.open(filename, os.O_WRONLY | os.O_CREAT, 0777)
+ count = os.write(fd, "hello world\n")
+ assert count == len("hello world\n")
+ os.close(fd)
+ fd = os.open(filename, os.O_RDONLY, 0777)
+ data = os.read(fd, 500)
+ assert data == "hello world\n"
+ os.close(fd)
+
+ f1 = compile(does_stuff, [])
+ f1()
+ assert open(filename, 'r').read() == "hello world\n"
+ os.unlink(filename)
More information about the Pypy-commit
mailing list