[pypy-commit] pypy file-support-in-rpython: start supporting open() in RPython

fijal noreply at buildbot.pypy.org
Tue Sep 17 16:26:10 CEST 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: file-support-in-rpython
Changeset: r66989:6354377ad204
Date: 2013-09-17 16:25 +0200
http://bitbucket.org/pypy/pypy/changeset/6354377ad204/

Log:	start supporting open() in RPython

diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rfile.py
@@ -0,0 +1,33 @@
+
+""" This file makes open() and friends RPython
+"""
+
+from rpython.annotator.model import SomeObject, SomeString
+from rpython.rtyper.extregistry import ExtRegistryEntry
+
+class SomeFile(SomeObject):
+    def method_write(self, s_arg):
+        assert isinstance(s_arg, SomeString)
+
+    def method_close(self):
+        pass
+
+    def rtyper_makekey(self):
+        return self.__class__,
+
+    def rtyper_makerepr(self, rtyper):
+        from rpython.rtyper.lltypesystem.rfile import FileRepr
+
+        return FileRepr(rtyper)
+
+class FileEntry(ExtRegistryEntry):
+    _about_ = open
+
+    def compute_result_annotation(self, s_name, s_mode=None):
+        assert isinstance(s_name, SomeString)
+        if s_mode is not None:
+            assert isinstance(s_mode, SomeString)
+        return SomeFile()
+
+    def specialize_call(self, hop):
+        return hop.r_result.rtype_constructor(hop)
diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/test/test_rfile.py
@@ -0,0 +1,16 @@
+
+from rpython.rtyper.test.tool import BaseRtypingTest
+from rpython.tool.udir import udir
+from rpython.rlib import rfile
+
+class TestFile(BaseRtypingTest):
+    def test_open(self):
+        fname = str(udir.join('test_file', 'file_1'))
+
+        def f():
+            f = open(fname, "w")
+            f.write("dupa")
+            f.close()
+
+        self.interpret(f, [])
+        assert open(fname, "r").read() == "dupa"
diff --git a/rpython/rtyper/lltypesystem/rfile.py b/rpython/rtyper/lltypesystem/rfile.py
new file mode 100644
--- /dev/null
+++ b/rpython/rtyper/lltypesystem/rfile.py
@@ -0,0 +1,59 @@
+
+import os
+from rpython.rlib import rposix
+from rpython.rtyper.rtyper import Repr
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.lltypesystem.rstr import string_repr
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.rtyper.annlowlevel import hlstr
+
+FILE = lltype.Struct('FILE') # opaque type maybe
+FILE_WRAPPER = lltype.GcStruct("FileWrapper", ('file', lltype.Ptr(FILE)))
+
+eci = ExternalCompilationInfo(includes=['stdio.h'])
+
+c_open = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP],
+                          lltype.Ptr(FILE), compilation_info=eci)
+
+def ll_open(name, mode):
+    file_wrapper = lltype.malloc(FILE_WRAPPER)
+    name = hlstr(name)
+    mode = hlstr(mode)
+    with rffi.scoped_str2charp(name) as ll_name:
+        with rffi.scoped_str2charp(mode) as ll_mode:
+            ll_f = c_open(ll_name, ll_mode)
+            if not ll_f:
+                errno = rposix.get_errno()
+                raise OSError(errno, os.strerror(errno))
+            file_wrapper.file = ll_f
+    return file_wrapper
+
+def ll_write(file_wrapper, value):
+    value = hlstr(value)
+    with rffi.scoped_str2charp(value) as ll_value:
+        pass
+
+def ll_close(file_wrapper):
+    pass
+
+class FileRepr(Repr):
+    lowleveltype = lltype.Ptr(FILE_WRAPPER)
+
+    def __init__(self, typer):
+        pass
+
+    def rtype_constructor(self, hop):
+        arg_0 = hop.inputarg(string_repr, 0)
+        arg_1 = hop.inputarg(string_repr, 1)
+        hop.exception_is_here()
+        return hop.gendirectcall(ll_open, arg_0, arg_1)
+
+    def rtype_method_write(self, hop):
+        args_v = hop.inputargs(self, string_repr)
+        hop.exception_is_here()
+        return hop.gendirectcall(ll_write, *args_v)
+
+    def rtype_method_close(self, hop):
+        r_self = hop.inputarg(self, 0)
+        hop.exception_is_here()
+        return hop.gendirectcall(ll_close, r_self)


More information about the pypy-commit mailing list