[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