[svn:parrot] r39472 - in trunk: . config/auto/sizes docs/book docs/book/draft docs/dev docs/pdds examples/languages/abc examples/languages/squaak include/parrot ports/cpan ports/cygwin ports/debian ports/fedora ports/mandriva ports/suse runtime/parrot/languages runtime/parrot/languages/parrot runtime/parrot/library/Math src/call src/gc src/interp src/io src/pmc src/runcore t/compilers/tge t/dynpmc t/native_pbc t/oo t/op t/pmc t/src tools/dev tools/util

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Tue Jun 9 15:07:28 UTC 2009


Author: whiteknight
Date: Tue Jun  9 15:07:24 2009
New Revision: 39472
URL: https://trac.parrot.org/parrot/changeset/39472

Log:
[io_rewiring] Merge the io_rewiring branch into trunk.

Added:
   trunk/src/pmc/handle.pmc
      - copied unchanged from r39460, branches/io_rewiring/src/pmc/handle.pmc
Modified:
   trunk/   (props changed)
   trunk/PBC_COMPAT
   trunk/config/auto/sizes/intval_maxmin_c.in   (props changed)
   trunk/docs/book/appb_patch_submission.pod   (props changed)
   trunk/docs/book/ch01_introduction.pod   (props changed)
   trunk/docs/book/ch03_pir.pod   (props changed)
   trunk/docs/book/ch04_compiler_tools.pod   (props changed)
   trunk/docs/book/ch07_dynpmcs.pod   (props changed)
   trunk/docs/book/ch08_dynops.pod   (props changed)
   trunk/docs/book/ch10_opcode_reference.pod   (props changed)
   trunk/docs/book/draft/chXX_hlls.pod   (props changed)
   trunk/docs/book/draft/chXX_library.pod   (props changed)
   trunk/docs/book/draft/chXX_testing_and_debugging.pod   (props changed)
   trunk/docs/dev/c_functions.pod   (props changed)
   trunk/docs/pdds/pdd30_install.pod   (props changed)
   trunk/examples/languages/abc/   (props changed)
   trunk/examples/languages/squaak/   (props changed)
   trunk/include/parrot/call.h   (props changed)
   trunk/include/parrot/gc_api.h   (props changed)
   trunk/include/parrot/io.h
   trunk/include/parrot/io_portable.h
   trunk/include/parrot/io_unix.h
   trunk/include/parrot/io_win32.h
   trunk/include/parrot/runcore_api.h   (props changed)
   trunk/include/parrot/runcore_trace.h   (props changed)
   trunk/ports/cpan/pause_guide.pod   (props changed)
   trunk/ports/cygwin/parrot-1.0.0-1.cygport   (props changed)
   trunk/ports/debian/libparrot-dev.install.in   (props changed)
   trunk/ports/debian/libparrot.install.in   (props changed)
   trunk/ports/debian/parrot-doc.install.in   (props changed)
   trunk/ports/debian/parrot.install.in   (props changed)
   trunk/ports/fedora/parrot.spec.fedora   (props changed)
   trunk/ports/mandriva/parrot.spec.mandriva   (props changed)
   trunk/ports/suse/parrot.spec.suse   (props changed)
   trunk/runtime/parrot/languages/   (props changed)
   trunk/runtime/parrot/languages/parrot/   (props changed)
   trunk/runtime/parrot/library/Math/Rand.pir   (props changed)
   trunk/src/call/ops.c   (props changed)
   trunk/src/call/pcc.c   (props changed)
   trunk/src/gc/alloc_memory.c   (props changed)
   trunk/src/gc/alloc_register.c   (props changed)
   trunk/src/gc/alloc_resources.c   (props changed)
   trunk/src/gc/api.c   (props changed)
   trunk/src/gc/generational_ms.c   (props changed)
   trunk/src/gc/incremental_ms.c   (props changed)
   trunk/src/gc/malloc.c   (props changed)
   trunk/src/gc/malloc_trace.c   (props changed)
   trunk/src/gc/mark_sweep.c   (props changed)
   trunk/src/gc/system.c   (props changed)
   trunk/src/interp/inter_cb.c   (props changed)
   trunk/src/interp/inter_create.c   (props changed)
   trunk/src/interp/inter_misc.c   (props changed)
   trunk/src/io/api.c
   trunk/src/io/buffer.c
   trunk/src/io/unix.c
   trunk/src/io/win32.c
   trunk/src/pmc/filehandle.pmc
   trunk/src/pmc/socket.pmc
   trunk/src/pmc/stringhandle.pmc
   trunk/src/runcore/cores.c   (props changed)
   trunk/src/runcore/main.c   (props changed)
   trunk/src/runcore/trace.c   (props changed)
   trunk/t/compilers/tge/NoneGrammar.tg   (props changed)
   trunk/t/dynpmc/pair.t   (props changed)
   trunk/t/native_pbc/annotations.pbc
   trunk/t/native_pbc/integer_1.pbc
   trunk/t/native_pbc/integer_4.pbc
   trunk/t/native_pbc/number_1.pbc
   trunk/t/native_pbc/number_2.pbc
   trunk/t/native_pbc/number_4.pbc
   trunk/t/native_pbc/number_5.pbc
   trunk/t/native_pbc/string_1.pbc
   trunk/t/native_pbc/string_4.pbc
   trunk/t/oo/root_new.t   (props changed)
   trunk/t/op/interp.t
   trunk/t/pmc/io.t
   trunk/t/pmc/pmc.t
   trunk/t/src/embed.t   (props changed)
   trunk/tools/dev/fetch_languages.pl   (props changed)
   trunk/tools/dev/mk_gitignore.pl   (props changed)
   trunk/tools/util/perlcritic-cage.conf   (props changed)

Modified: trunk/PBC_COMPAT
==============================================================================
--- trunk/PBC_COMPAT	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/PBC_COMPAT	Tue Jun  9 15:07:24 2009	(r39472)
@@ -27,6 +27,7 @@
 
 # please insert tab separated entries at the top of the list
 
+4.8	2009.05.30	Infinoid	Added Handle PMC
 4.7	2009.05.29	cotto	add cmp_pmc opcode (also, addition of setstdin and root_new in previous commits)
 4.6	2009.05.18	bacek	removed PackfileAnnotationKeys PMC
 4.5	2009.04.10	cotto	removed Ref and SharedRef PMCs

Modified: trunk/include/parrot/io.h
==============================================================================
--- trunk/include/parrot/io.h	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/include/parrot/io.h	Tue Jun  9 15:07:24 2009	(r39472)
@@ -150,6 +150,10 @@
         FUNC_MODIFIES(*pmc);
 
 PARROT_EXPORT
+INTVAL Parrot_io_close_piohandle(PARROT_INTERP, PIOHANDLE handle)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL Parrot_io_eof(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
@@ -229,10 +233,9 @@
 PARROT_CANNOT_RETURN_NULL
 PMC * Parrot_io_open(PARROT_INTERP,
     ARGIN_NULLOK(PMC *pmc),
-    ARGIN(STRING *path),
+    ARGIN_NULLOK(STRING *path),
     ARGIN_NULLOK(STRING *mode))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3);
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
@@ -352,6 +355,8 @@
 #define ASSERT_ARGS_Parrot_io_close __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_io_close_piohandle __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_eof __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
@@ -380,8 +385,7 @@
 #define ASSERT_ARGS_Parrot_io_new_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_open __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(path)
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_peek __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc) \

Modified: trunk/include/parrot/io_portable.h
==============================================================================
--- trunk/include/parrot/io_portable.h	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/include/parrot/io_portable.h	Tue Jun  9 15:07:24 2009	(r39472)
@@ -16,6 +16,8 @@
 typedef FILE* PIOHANDLE;
 typedef long PIOOFF_T;
 
+#define PIO_INVALID_HANDLE NULL
+
 /* HEADERIZER BEGIN: src/io/portable.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 

Modified: trunk/include/parrot/io_unix.h
==============================================================================
--- trunk/include/parrot/io_unix.h	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/include/parrot/io_unix.h	Tue Jun  9 15:07:24 2009	(r39472)
@@ -18,6 +18,8 @@
 typedef INTVAL PIOHANDLE;
 typedef off_t PIOOFF_T;
 
+#define PIO_INVALID_HANDLE -1
+
 /* HEADERIZER BEGIN: src/io/unix.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
@@ -28,6 +30,7 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*filehandle);
 
+INTVAL Parrot_io_close_piohandle_unix(SHIM_INTERP, PIOHANDLE handle);
 INTVAL Parrot_io_close_unix(PARROT_INTERP, ARGMOD(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -82,6 +85,16 @@
     SHIM(STRING **buf))
         __attribute__nonnull__(1);
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+INTVAL Parrot_io_pipe_unix(SHIM_INTERP,
+    ARGMOD(PIOHANDLE *reader),
+    ARGMOD(PIOHANDLE *writer))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*reader)
+        FUNC_MODIFIES(*writer);
+
 size_t Parrot_io_read_unix(PARROT_INTERP,
     ARGMOD(PMC *filehandle),
     ARGIN(STRING **buf))
@@ -114,6 +127,8 @@
 #define ASSERT_ARGS_Parrot_io_async_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
+#define ASSERT_ARGS_Parrot_io_close_piohandle_unix \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_Parrot_io_close_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
@@ -138,6 +153,9 @@
     || PARROT_ASSERT_ARG(path)
 #define ASSERT_ARGS_Parrot_io_peek_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_io_pipe_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(reader) \
+    || PARROT_ASSERT_ARG(writer)
 #define ASSERT_ARGS_Parrot_io_read_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle) \
@@ -269,6 +287,7 @@
 #define PIO_OPEN_PIPE(interp, pmc, file, flags) \
     Parrot_io_open_pipe_unix((interp), (pmc), (file), (flags))
 #define PIO_CLOSE(interp, pmc) Parrot_io_close_unix((interp), (pmc))
+#define PIO_CLOSE_PIOHANDLE(interp, handle) Parrot_io_close_piohandle_unix((interp), (handle))
 #define PIO_IS_CLOSED(interp, pmc) Parrot_io_is_closed_unix((interp), (pmc))
 #define PIO_READ(interp, pmc, buf) Parrot_io_read_unix((interp), (pmc), (buf))
 #define PIO_WRITE(interp, pmc, str) Parrot_io_write_unix((interp), (pmc), (str))
@@ -281,6 +300,8 @@
 
 #define PIO_POLL(interp, pmc, which, sec, usec) \
     Parrot_io_poll_unix((interp), (pmc), (which), (sec), (usec))
+#define PIO_PIPE(interp, reader, writer) \
+    Parrot_io_pipe_unix((interp), (reader), (writer))
 #define PIO_SOCKET(interp, socket, fam, type, proto) \
     Parrot_io_socket_unix((interp), (socket), (fam), (type), (proto))
 #define PIO_RECV(interp, pmc, buf) \

Modified: trunk/include/parrot/io_win32.h
==============================================================================
--- trunk/include/parrot/io_win32.h	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/include/parrot/io_win32.h	Tue Jun  9 15:07:24 2009	(r39472)
@@ -16,9 +16,14 @@
 typedef Parrot_WIN32_HANDLE PIOHANDLE;
 typedef Parrot_OFF_T PIOOFF_T;
 
+#define PIO_INVALID_HANDLE INVALID_HANDLE_VALUE
+
 /* HEADERIZER BEGIN: src/io/win32.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+INTVAL Parrot_io_close_piohandle_win32(PARROT_INTERP, PIOHANDLE handle)
+        __attribute__nonnull__(1);
+
 INTVAL Parrot_io_close_win32(PARROT_INTERP, ARGMOD(PMC *filehandle))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -72,6 +77,16 @@
     SHIM(STRING **buf))
         __attribute__nonnull__(1);
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+INTVAL Parrot_io_pipe_win32(SHIM_INTERP,
+    ARGMOD(PIOHANDLE *reader),
+    ARGMOD(PIOHANDLE *writer))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*reader)
+        FUNC_MODIFIES(*writer);
+
 size_t Parrot_io_read_win32(PARROT_INTERP,
     ARGMOD(PMC *filehandle),
     ARGOUT(STRING **buf))
@@ -100,6 +115,9 @@
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
 
+#define ASSERT_ARGS_Parrot_io_close_piohandle_win32 \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_io_close_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle)
@@ -124,6 +142,9 @@
     || PARROT_ASSERT_ARG(path)
 #define ASSERT_ARGS_Parrot_io_peek_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_io_pipe_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(reader) \
+    || PARROT_ASSERT_ARG(writer)
 #define ASSERT_ARGS_Parrot_io_read_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(filehandle) \
@@ -251,6 +272,7 @@
 #define PIO_OPEN_PIPE(interp, pmc, file, flags) \
     Parrot_io_open_pipe_win32((interp), (pmc), (file), (flags))
 #define PIO_CLOSE(interp, pmc) Parrot_io_close_win32((interp), (pmc))
+#define PIO_CLOSE_PIOHANDLE(interp, handle) Parrot_io_close_piohandle_win32((interp), (handle))
 #define PIO_IS_CLOSED(interp, pmc) Parrot_io_is_closed_win32((interp), (pmc))
 #define PIO_READ(interp, pmc, buf) Parrot_io_read_win32((interp), (pmc), (buf))
 #define PIO_WRITE(interp, pmc, str) Parrot_io_write_win32((interp), (pmc), (str))
@@ -263,6 +285,8 @@
 
 #define PIO_POLL(interp, pmc, which, sec, usec) \
     Parrot_io_poll_win32((interp), (pmc), (which), (sec), (usec))
+#define PIO_PIPE(interp, reader, writer) \
+    Parrot_io_pipe_win32((interp), (reader), (writer))
 #define PIO_SOCKET(interp, socket, fam, type, proto) \
     Parrot_io_socket_win32((interp), (socket), (fam), (type), (proto))
 #define PIO_RECV(interp, pmc, buf) \

Modified: trunk/src/io/api.c
==============================================================================
--- trunk/src/io/api.c	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/io/api.c	Tue Jun  9 15:07:24 2009	(r39472)
@@ -19,6 +19,10 @@
 The C<FileHandle> PMC provides the class-based interface for filehandles that
 is used in Parrot ops.
 
+TODO: Where possible, extract some of the filehandle-related details into
+src/io/filehandle.c, and extract the stringhandle details into
+src/io/io_string.c.
+
 =cut
 
 */
@@ -26,6 +30,8 @@
 #include "parrot/parrot.h"
 #include "io_private.h"
 #include "api.str"
+#include "../pmc/pmc_filehandle.h"
+#include "../pmc/pmc_stringhandle.h"
 
 #include <stdarg.h>
 
@@ -111,20 +117,42 @@
 PARROT_CANNOT_RETURN_NULL
 PMC *
 Parrot_io_open(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc),
-        ARGIN(STRING *path), ARGIN_NULLOK(STRING *mode))
+        ARGIN_NULLOK(STRING *path), ARGIN_NULLOK(STRING *mode))
 {
     ASSERT_ARGS(Parrot_io_open)
-    PMC *new_filehandle;
-
-    if (PMC_IS_NULL(pmc))
+    PMC *new_filehandle, *filehandle;
+    INTVAL flags;
+    if (PMC_IS_NULL(pmc)) {
+        /* TODO: We should look up the HLL mapped type, instead of always
+           using FileHandle here */
         new_filehandle = pmc_new(interp, enum_class_FileHandle);
+        PARROT_ASSERT(new_filehandle->vtable->base_type == enum_class_FileHandle);
+    }
     else
         new_filehandle = pmc;
 
-    Parrot_PCCINVOKE(interp, new_filehandle, CONST_STRING(interp, "open"), "SS->P",
-            path, mode, &new_filehandle);
-
-    return new_filehandle;
+    flags = Parrot_io_parse_open_flags(interp, mode);
+    if (new_filehandle->vtable->base_type == enum_class_FileHandle) {
+        /* TODO: StringHandle may have a null path, but a filehandle really
+           shouldn't allow that. */
+        PARROT_ASSERT(new_filehandle->vtable->base_type == enum_class_FileHandle);
+        filehandle = PIO_OPEN(interp, new_filehandle, path, flags);
+        if (PMC_IS_NULL(filehandle))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Unable to open filehandle from path '%S'", path);
+        PARROT_ASSERT(filehandle->vtable->base_type == enum_class_FileHandle);
+        SETATTR_FileHandle_flags(interp, new_filehandle, flags);
+        SETATTR_FileHandle_filename(interp, new_filehandle, path);
+        SETATTR_FileHandle_mode(interp, new_filehandle, mode);
+        Parrot_io_setbuf(interp, filehandle, PIO_UNBOUND);
+    }
+    else if (new_filehandle->vtable->base_type == enum_class_StringHandle) {
+        SETATTR_StringHandle_flags(interp, pmc, flags);
+        filehandle = pmc;
+    }
+    else
+        Parrot_PCCINVOKE(interp, new_filehandle, CONST_STRING(interp, "read"), "SS->P", path, mode, &open);
+    return filehandle;
 }
 
 /*
@@ -187,16 +215,45 @@
 Parrot_io_close(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_io_close)
-    INTVAL result;
+    INTVAL result = 1;
 
     if (PMC_IS_NULL(pmc))
         return -1;
 
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "close"), "->I", &result);
+    if (pmc->vtable->base_type == enum_class_FileHandle) {
+        result = Parrot_io_close_filehandle(interp, pmc);
+        SETATTR_FileHandle_flags(interp, pmc, 0);
+    }
+    else if (pmc->vtable->base_type == enum_class_StringHandle) {
+        SETATTR_StringHandle_read_offset(interp, pmc, 0);
+    }
+    else
+        Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "close"), "->I", &result);
 
     return result;
 }
 
+
+/*
+
+=item C<INTVAL Parrot_io_close_piohandle(PARROT_INTERP, PIOHANDLE handle)>
+
+Calls close() on the given PIOHANDLE.  This is the low level OS-specific close()
+function, intended to be called directly by PMC destroy() vtables.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+INTVAL
+Parrot_io_close_piohandle(PARROT_INTERP, PIOHANDLE handle)
+{
+    ASSERT_ARGS(Parrot_io_close_piohandle)
+    return PIO_CLOSE_PIOHANDLE(interp, handle);
+}
+
+
 /*
 
 =item C<INTVAL Parrot_io_is_closed(PARROT_INTERP, PMC *pmc)>
@@ -214,12 +271,20 @@
 Parrot_io_is_closed(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_io_is_closed)
-    INTVAL result;
+    INTVAL result = 1;
 
     if (PMC_IS_NULL(pmc))
         return 1;
+    if (pmc->vtable->base_type == enum_class_FileHandle)
+        result = Parrot_io_is_closed_filehandle(interp, pmc);
+    else if (pmc->vtable->base_type == enum_class_StringHandle) {
+        STRING *stringhandle;
+        GETATTR_StringHandle_stringhandle(interp, pmc, stringhandle);
+        result = STRING_IS_NULL(stringhandle);
+    }
+    else
+        Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "is_closed"), "->I", &result);
 
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "is_closed"), "->I", &result);
     return result;
 }
 
@@ -242,7 +307,13 @@
     if (PMC_IS_NULL(pmc))
         return;
 
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "flush"), "->");
+    if (pmc->vtable->base_type == enum_class_FileHandle)
+        Parrot_io_flush_filehandle(interp, pmc);
+    else if (pmc->vtable->base_type == enum_class_StringHandle) {
+        SETATTR_StringHandle_stringhandle(interp, pmc, NULL);
+    }
+    else
+        Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "flush"), "->");
 }
 
 /*
@@ -264,9 +335,57 @@
 Parrot_io_reads(PARROT_INTERP, ARGMOD(PMC *pmc), size_t length)
 {
     ASSERT_ARGS(Parrot_io_reads)
-    STRING *result;
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "read"), "I->S",
-            length, &result);
+    STRING *result = NULL;
+    if (PMC_IS_NULL(pmc))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+            "Attempt to read from null or invalid PMC");
+    if (pmc->vtable->base_type == enum_class_FileHandle) {
+        INTVAL ignored;
+        INTVAL flags;
+        GETATTR_FileHandle_flags(interp, pmc, flags);
+
+        if (Parrot_io_is_closed_filehandle(interp, pmc)
+        || !(flags & PIO_F_READ))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Cannot read from a closed or non-readable filehandle");
+
+        result = Parrot_io_make_string(interp, &result, length);
+        result->bufused = length;
+
+        if (Parrot_io_is_encoding(interp, pmc, CONST_STRING(interp, "utf8")))
+            ignored = Parrot_io_read_utf8(interp, pmc, &result);
+        else
+            ignored = Parrot_io_read_buffer(interp, pmc, &result);
+    }
+    else if (pmc->vtable->base_type == enum_class_StringHandle) {
+        STRING *string_orig;
+        INTVAL offset;
+        /* TODO: Check that we are open for reading */
+        GETATTR_StringHandle_stringhandle(interp, pmc, string_orig);
+        if (STRING_IS_NULL(string_orig))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Cannot read from a closed filehandle");
+
+        if (length == 0)
+            result = Parrot_str_copy(interp, string_orig);
+        else {
+            INTVAL orig_length, read_length;
+            read_length = length;
+            orig_length = Parrot_str_byte_length(interp, string_orig);
+
+            GETATTR_StringHandle_read_offset(interp, pmc, offset);
+
+            /* Only read to the end of the string data. */
+            if (offset + read_length > orig_length)
+                read_length = orig_length - offset;
+
+            result = Parrot_str_substr(interp, string_orig, offset,
+                    read_length, NULL, 0);
+            SETATTR_StringHandle_read_offset(interp, pmc, offset + read_length);
+        }
+    }
+    else
+        Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "read"), "I->S", length, &result);
     return result;
 }
 
@@ -290,8 +409,41 @@
 {
     ASSERT_ARGS(Parrot_io_readline)
     STRING *result;
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "readline"), "->S",
-            &result);
+    if (pmc->vtable->base_type == enum_class_FileHandle) {
+        INTVAL flags;
+        if (Parrot_io_is_closed_filehandle(interp, pmc))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Cannot read from a closed filehandle");
+        GETATTR_FileHandle_flags(interp, pmc, flags);
+        if (!(flags & PIO_F_LINEBUF))
+            Parrot_io_setlinebuf(interp, pmc);
+
+        result = Parrot_io_reads(interp, pmc, 0);
+    }
+    else if (pmc->vtable->base_type == enum_class_StringHandle) {
+        INTVAL offset, newline_pos, read_length, orig_length;
+
+        GETATTR_StringHandle_stringhandle(interp, pmc, result);
+        if (STRING_IS_NULL(result))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Cannot read from a closed stringhandle");
+
+        orig_length = Parrot_str_byte_length(interp, result);
+        GETATTR_StringHandle_read_offset(interp, pmc, offset);
+        newline_pos = Parrot_str_find_index(interp, result, CONST_STRING(interp, "\n"), offset);
+
+        /* No newline found, read the rest of the string. */
+        if (newline_pos == -1)
+            read_length = orig_length - offset;
+        else
+            read_length = newline_pos - offset + 1; /* +1 to include the newline */
+
+        result = Parrot_str_substr(interp, result, offset,
+                read_length, NULL, 0);
+        SETATTR_StringHandle_read_offset(interp, pmc, newline_pos + 1);
+    }
+    else
+        Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "readline"), "->S", &result);
     return result;
 }
 
@@ -416,19 +568,24 @@
 Parrot_io_eof(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_io_eof)
-    INTVAL result;
+    INTVAL flags, result;
 
     /* io could be null here, but rather than return a negative error
      * we just fake EOF since eof test is usually in a boolean context.
      */
     if (PMC_IS_NULL(pmc))
+        return 1;
+    if (pmc->vtable->base_type == enum_class_FileHandle) {
+        if (Parrot_io_is_closed_filehandle(interp, pmc))
             return 1;
 
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "eof"), "->I",
-            &result);
-
+        GETATTR_FileHandle_flags(interp, pmc, flags);
+        if (flags & PIO_F_EOF)
+            return 1;
+        return 0;
+    }
+    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "eof"), "->I", &result);
     return result;
-
 }
 
 /*
@@ -470,9 +627,23 @@
     if (PMC_IS_NULL(pmc))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
             "Cannot write to null PMC");
+    if (pmc->vtable->base_type == enum_class_FileHandle) {
+        INTVAL flags;
+        GETATTR_FileHandle_flags(interp, pmc, flags);
+
+        if (!(flags & PIO_F_WRITE))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "FileHandle is not opened for writing");
+        if (STRING_IS_NULL(s))
+            return 0;
+        if (Parrot_io_is_encoding(interp, pmc, CONST_STRING(interp, "utf8")))
+            result = Parrot_io_write_utf8(interp, pmc, s);
+        else
+            result = Parrot_io_write_buffer(interp, pmc, s);
+    }
+    else
+        Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "puts"), "S->I", s, &result);
 
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "puts"), "S->I",
-            s, &result);
     return result;
 
 }

Modified: trunk/src/io/buffer.c
==============================================================================
--- trunk/src/io/buffer.c	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/io/buffer.c	Tue Jun  9 15:07:24 2009	(r39472)
@@ -79,7 +79,7 @@
 
     /* If there is already a buffer, make sure we flush before modifying it. */
     if (buffer_start)
-        Parrot_io_flush(interp, filehandle);
+        Parrot_io_flush_buffer(interp, filehandle);
 
     /* Choose an appropriate buffer size for caller */
     switch (bufsize) {
@@ -286,7 +286,7 @@
 
     /* write buffer flush */
     if (buffer_flags & PIO_BF_WRITEBUF) {
-        Parrot_io_flush(interp, filehandle);
+        Parrot_io_flush_buffer(interp, filehandle);
         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
     }
 
@@ -416,7 +416,7 @@
 
     /* write buffer flush */
     if (buffer_flags & PIO_BF_WRITEBUF) {
-        Parrot_io_flush(interp, filehandle);
+        Parrot_io_flush_buffer(interp, filehandle);
         buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
     }
 
@@ -623,7 +623,7 @@
         long wrote;
 
         /* Write through, skip buffer. */
-        Parrot_io_flush(interp, filehandle);
+        Parrot_io_flush_buffer(interp, filehandle);
         wrote = PIO_WRITE(interp, filehandle, s);
 
         if (wrote == (long)len) {
@@ -658,7 +658,7 @@
         Parrot_io_set_buffer_next(interp, filehandle, buffer_next);
         Parrot_io_set_file_position(interp, filehandle, (avail +
                     Parrot_io_get_file_position(interp, filehandle)));
-        Parrot_io_flush(interp, filehandle);
+        Parrot_io_flush_buffer(interp, filehandle);
 
         buffer_flags |= PIO_BF_WRITEBUF;
         Parrot_io_set_buffer_flags(interp, filehandle, buffer_flags);
@@ -718,7 +718,7 @@
 
     if ((newpos < file_pos - (buffer_next - buffer_start))
         || (newpos >= file_pos + (buffer_end - buffer_next))) {
-        Parrot_io_flush(interp, filehandle);
+        Parrot_io_flush_buffer(interp, filehandle);
         newpos = PIO_SEEK(interp, filehandle, newpos, SEEK_SET);
     }
     else {

Modified: trunk/src/io/unix.c
==============================================================================
--- trunk/src/io/unix.c	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/io/unix.c	Tue Jun  9 15:07:24 2009	(r39472)
@@ -35,6 +35,7 @@
 
 #  include <sys/types.h>
 #  include <sys/wait.h>
+#  include <unistd.h> /* for pipe() */
 
 /* HEADERIZER HFILE: include/parrot/io_unix.h */
 
@@ -357,6 +358,24 @@
     return result;
 }
 
+
+/*
+
+=item C<INTVAL Parrot_io_close_piohandle_unix(PARROT_INTERP, PIOHANDLE handle)>
+
+Closes the given file descriptor.  Returns 0 on success, -1 on error.
+
+=cut
+
+*/
+
+INTVAL
+Parrot_io_close_piohandle_unix(SHIM_INTERP, PIOHANDLE handle)
+{
+    ASSERT_ARGS(Parrot_io_close_piohandle_unix)
+    return close(handle);
+}
+
 /*
 
 =item C<INTVAL Parrot_io_is_closed_unix(PARROT_INTERP, PMC *filehandle)>
@@ -767,6 +786,33 @@
 }
 
 
+/*
+
+=item C<INTVAL Parrot_io_pipe_unix(PARROT_INTERP, PIOHANDLE *reader, PIOHANDLE
+*writer)>
+
+Uses C<pipe()> to create a matched pair of pipe fds.  Returns 0 on success, -1
+on failure.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+INTVAL
+Parrot_io_pipe_unix(SHIM_INTERP, ARGMOD(PIOHANDLE *reader), ARGMOD(PIOHANDLE *writer))
+{
+    ASSERT_ARGS(Parrot_io_pipe_unix)
+    int fds[2], rv;
+    rv = pipe(fds);
+    if (rv >= 0) {
+        *reader = fds[0];
+        *writer = fds[1];
+    }
+    return rv;
+}
+
 #endif /* PIO_OS_UNIX */
 
 /*

Modified: trunk/src/io/win32.c
==============================================================================
--- trunk/src/io/win32.c	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/io/win32.c	Tue Jun  9 15:07:24 2009	(r39472)
@@ -295,6 +295,28 @@
 
 /*
 
+=item C<INTVAL Parrot_io_close_piohandle_win32(PARROT_INTERP, PIOHANDLE handle)>
+
+Calls C<CloseHandle()> to close the given file descriptor.  Returns 0 on
+success, -1 on error.
+
+=cut
+
+*/
+
+INTVAL
+Parrot_io_close_piohandle_win32(PARROT_INTERP, PIOHANDLE handle)
+{
+    ASSERT_ARGS(Parrot_io_close_piohandle_win32)
+
+    if (handle == INVALID_HANDLE_VALUE)
+        return -1;
+
+    return CloseHandle(handle) ? 0 : -1;
+}
+
+/*
+
 =item C<INTVAL Parrot_io_close_win32(PARROT_INTERP, PMC *filehandle)>
 
 Calls C<CloseHandle()> to close C<*io>'s file descriptor.
@@ -704,6 +726,27 @@
         "pipe open error");
 }
 
+/*
+
+=item C<INTVAL Parrot_io_pipe_win32(PARROT_INTERP, PIOHANDLE *reader, PIOHANDLE
+*writer)>
+
+Uses CreatePipe() to create a matched pair of pipe handles.  Returns 0 on
+success, -1 on failure.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+INTVAL
+Parrot_io_pipe_win32(SHIM_INTERP, ARGMOD(PIOHANDLE *reader), ARGMOD(PIOHANDLE *writer))
+{
+    ASSERT_ARGS(Parrot_io_pipe_win32)
+    return CreatePipe(reader, writer, NULL, 0) ? 0 : -1;
+}
+
 #endif /* PIO_OS_WIN32 */
 
 /*

Modified: trunk/src/pmc/filehandle.pmc
==============================================================================
--- trunk/src/pmc/filehandle.pmc	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/pmc/filehandle.pmc	Tue Jun  9 15:07:24 2009	(r39472)
@@ -31,24 +31,11 @@
 #endif
 #endif
 
-#ifdef PIO_OS_WIN32
-#  define PIO_INVALID_HANDLE INVALID_HANDLE_VALUE
-#endif
-
-#ifdef PIO_OS_UNIX
-#  define PIO_INVALID_HANDLE -1
-#endif
-
-#ifdef PIO_OS_STDIO
-#  define PIO_INVALID_HANDLE NULL
-#endif
-
-pmclass FileHandle need_ext {
+pmclass FileHandle extends Handle {
     ATTR INTVAL flags;                /* Filehandle flags             */
     ATTR STRING *filename;            /* The opened path and filename */
     ATTR STRING *mode;                /* The mode string used in open */
     ATTR STRING *encoding;            /* The encoding for read/write  */
-    ATTR PIOHANDLE os_handle;         /* Low level OS descriptor      */
     ATTR INTVAL process_id;           /* Child process on pipes       */
     ATTR PIOOFF_T file_size;          /* Current file size            */
     ATTR PIOOFF_T file_pos;           /* Current real file pointer    */
@@ -248,10 +235,9 @@
 */
 
     METHOD open(STRING *filename :optional, INTVAL got_filename :opt_flag,
-                STRING *mode :optional, INTVAL got_mode :opt_flag) {
+        STRING *mode :optional, INTVAL got_mode :opt_flag) {
         PMC *filehandle;
         STRING *open_filename, *open_mode;
-        INTVAL flags;
 
         if (!Parrot_io_is_closed_filehandle(INTERP, SELF))
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
@@ -278,16 +264,7 @@
             SET_ATTR_mode(INTERP, SELF, open_mode);
         }
 
-        flags = Parrot_io_parse_open_flags(interp, open_mode);
-        SET_ATTR_flags(INTERP, SELF, flags);
-        filehandle = PIO_OPEN(INTERP, SELF, open_filename, flags);
-
-        if (PMC_IS_NULL(filehandle))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Unable to open filehandle from path '%S'",
-                open_filename);
-
-        Parrot_io_setbuf(interp, filehandle, PIO_UNBOUND);
+        filehandle = Parrot_io_open(INTERP, SELF, open_filename, open_mode);
 
         RETURN(PMC *filehandle);
     }
@@ -316,7 +293,7 @@
 
     METHOD close() {
         INTVAL status;
-        status = Parrot_io_close_filehandle(interp, SELF);
+        status = Parrot_io_close(INTERP, SELF);
         RETURN(INTVAL status);
     }
 
@@ -332,7 +309,7 @@
 
     METHOD is_closed() {
         INTVAL status;
-        status = Parrot_io_is_closed_filehandle(interp, SELF);
+        status = Parrot_io_is_closed(interp, SELF);
         RETURN(INTVAL status);
     }
 
@@ -348,19 +325,7 @@
 
     METHOD read(INTVAL length) {
         STRING *string_result = NULL;
-        INTVAL  ignored;
-
-        if (Parrot_io_is_closed_filehandle(interp, SELF))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot read from a closed filehandle");
-
-        string_result = Parrot_io_make_string(interp, &string_result, length);
-        string_result->bufused = length;
-
-        if (Parrot_io_is_encoding(interp, SELF, CONST_STRING(interp, "utf8")))
-            ignored = Parrot_io_read_utf8(interp, SELF, &string_result);
-        else
-            ignored = Parrot_io_read_buffer(interp, SELF, &string_result);
+        string_result = Parrot_io_reads(INTERP, SELF, length);
 
         RETURN(STRING *string_result);
     }
@@ -377,11 +342,7 @@
 
     METHOD readline() {
         STRING *string_result;
-        if (!(PARROT_FILEHANDLE(SELF)->flags & PIO_F_LINEBUF))
-            Parrot_io_setlinebuf(INTERP, SELF);
-
-        string_result = Parrot_io_reads(INTERP, SELF, 0);
-
+        string_result = Parrot_io_readline(INTERP, SELF);
         RETURN(STRING *string_result);
     }
 
@@ -471,6 +432,7 @@
                                 "Cannot readall on a new file from an already open filehandle");
             }
             filehandle  = Parrot_io_open(INTERP, PMCNULL, name, NULL);
+            PARROT_ASSERT(filehandle->vtable->base_type == enum_class_FileHandle);
             SET_ATTR_encoding(INTERP, filehandle, encoding);
             size = (size_t)(Parrot_stat_info_intval(INTERP, name, STAT_FILESIZE));
 
@@ -513,7 +475,7 @@
 */
 
     METHOD flush() {
-        Parrot_io_flush_filehandle(interp, SELF);
+        Parrot_io_flush(INTERP, SELF);
     }
 
 /*
@@ -544,30 +506,8 @@
 */
 
     METHOD puts(STRING *to_print) {
-        INTVAL flags, status;
-        if (Parrot_io_is_closed_filehandle(interp, SELF))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot write to a closed filehandle");
-
-        GET_ATTR_flags(INTERP, SELF, flags);
-        if (!(flags & PIO_F_WRITE))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot write to a filehandle not opened for write");
-
-        if (STRING_IS_NULL(to_print))
-            RETURN(INTVAL 0);
-
-#if ! DISABLE_GC_DEBUG
-        /* trigger GC for debug - but not during tests */
-        if (0 && GC_DEBUG(interp))
-            Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
-#endif
-
-        if (Parrot_io_is_encoding(interp, SELF, CONST_STRING(interp, "utf8")))
-            status = Parrot_io_write_utf8(interp, SELF, to_print);
-        else
-            status = Parrot_io_write_buffer(interp, SELF, to_print);
-
+        INTVAL status;
+        status = Parrot_io_putps(INTERP, SELF, to_print);
         RETURN(INTVAL status);
     }
 
@@ -707,14 +647,8 @@
 
     METHOD eof() {
         INTVAL flags;
-        if (Parrot_io_is_closed_filehandle(interp, SELF))
-            RETURN(INTVAL 1);
-
-        GET_ATTR_flags(INTERP, SELF, flags);
-        if (flags & PIO_F_EOF)
-            RETURN(INTVAL 1);
-
-        RETURN(INTVAL 0);
+        flags = Parrot_io_eof(INTERP, SELF);
+        RETURN(INTVAL flags);
     }
 
 

Copied: trunk/src/pmc/handle.pmc (from r39460, branches/io_rewiring/src/pmc/handle.pmc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/pmc/handle.pmc	Tue Jun  9 15:07:24 2009	(r39472, copy of r39460, branches/io_rewiring/src/pmc/handle.pmc)
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 2008, Parrot Foundation.
+$Id: socket.pmc 38794 2009-05-15 16:12:33Z coke $
+
+=head1 NAME
+
+src/pmc/handle.pmc - IO Handle PMC
+
+=head1 DESCRIPTION
+
+This is the base-class for all IO-related PMCs.
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "../src/io/io_private.h"
+
+pmclass Handle provides Handle {
+    /* TODO: Consider encapsulating PIOHANDLE as a PMC type, for subclassing */
+    ATTR PIOHANDLE os_handle;         /* Low level OS descriptor      */
+
+    VTABLE void init() {
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Handle cannot be instantiated directly.");
+    }
+
+    VTABLE void init_pmc(PMC * init) {
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Handle cannot be instantiated directly.");
+    }
+}
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: trunk/src/pmc/socket.pmc
==============================================================================
--- trunk/src/pmc/socket.pmc	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/pmc/socket.pmc	Tue Jun  9 15:07:24 2009	(r39472)
@@ -20,7 +20,7 @@
 
 #include "../src/io/io_private.h"
 
-pmclass Socket extends FileHandle need_ext {
+pmclass Socket extends Handle {
     ATTR PMC *local;           /* Local addr                   */
     ATTR PMC *remote;          /* Remote addr                  */
 
@@ -49,7 +49,7 @@
 
 =item C<PMC *clone()>
 
-Create a copy of the filehandle.
+Create a copy of the socket handle.
 
 =cut
 
@@ -68,9 +68,24 @@
 
 /*
 
+=item C<INTVAL does(STRING * role)>
+
+=cut
+
+*/
+
+    VTABLE INTVAL does(STRING * role) {
+        Parrot_Socket_attributes * const attrs = PARROT_SOCKET(SELF);
+        if (Parrot_str_equal(interp, role, CONST_STRING(interp, "socket")))
+            return 1;
+        return SUPER(role);
+    }
+
+/*
+
 =item C<void mark()>
 
-Mark active filehandle data as live.
+Mark active socket handle data as live.
 
 =cut
 
@@ -100,7 +115,9 @@
         if (PARROT_SOCKET(SELF)) {
             Parrot_Socket_attributes *data_struct = PARROT_SOCKET(SELF);
 
-            /* TODO Shutdown socket */
+            if(data_struct->os_handle != PIO_INVALID_HANDLE)
+                Parrot_io_close_piohandle(interp, data_struct->os_handle);
+            data_struct->os_handle = PIO_INVALID_HANDLE;
         }
     }
 

Modified: trunk/src/pmc/stringhandle.pmc
==============================================================================
--- trunk/src/pmc/stringhandle.pmc	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/src/pmc/stringhandle.pmc	Tue Jun  9 15:07:24 2009	(r39472)
@@ -46,7 +46,7 @@
         return Parrot_str_equal(interp, s, CONST_STRING(interp, "utf8"));
 }
 
-pmclass StringHandle need_ext {
+pmclass StringHandle extends Handle need_ext {
     ATTR INTVAL  flags;               /* Filehandle flags             */
     ATTR STRING *stringhandle;        /* The string data              */
     ATTR STRING *mode;                /* The mode string used in open */
@@ -220,8 +220,7 @@
             SET_ATTR_mode(INTERP, SELF, open_mode);
         }
 
-        flags = Parrot_io_parse_open_flags(interp, open_mode);
-        SET_ATTR_flags(INTERP, SELF, flags);
+        Parrot_io_open(INTERP, SELF, filename, open_mode);
 
         RETURN(PMC *SELF);
     }
@@ -266,13 +265,9 @@
 */
 
     METHOD is_closed() {
-        STRING *stringhandle;
-        GET_ATTR_stringhandle(INTERP, SELF, stringhandle);
-
-        if (STRING_IS_NULL(stringhandle))
-            RETURN(INTVAL 1);
-
-        RETURN(INTVAL 0);
+        INTVAL status;
+        status = Parrot_io_is_closed(INTERP, SELF);
+        RETURN(INTVAL status);
     }
 
 /*
@@ -287,32 +282,8 @@
 */
 
     METHOD read(INTVAL length) {
-        STRING *string_result, *string_orig;
-        INTVAL offset;
-
-        GET_ATTR_stringhandle(INTERP, SELF, string_orig);
-        if (STRING_IS_NULL(string_orig))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot read from a closed filehandle");
-
-        if (length == 0)
-            string_result = Parrot_str_copy(INTERP, string_orig);
-        else {
-            INTVAL orig_length, read_length;
-            read_length = length;
-            orig_length = Parrot_str_byte_length(INTERP, string_orig);
-
-            GET_ATTR_read_offset(INTERP, SELF, offset);
-
-            /* Only read to the end of the string data. */
-            if (offset + read_length > orig_length)
-                read_length = orig_length - offset;
-
-            string_result = Parrot_str_substr(INTERP, string_orig, offset,
-                    read_length, NULL, 0);
-            SET_ATTR_read_offset(INTERP, SELF, offset + read_length);
-        }
-
+        STRING *string_result;
+        string_result = Parrot_io_reads(INTERP, SELF, length);
         RETURN(STRING *string_result);
     }
 
@@ -329,27 +300,7 @@
 
     METHOD readline() {
         STRING *string_result;
-        INTVAL offset, newline_pos, read_length, orig_length;
-
-        GET_ATTR_stringhandle(INTERP, SELF, string_result);
-        if (STRING_IS_NULL(string_result))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot read from a closed filehandle");
-
-        orig_length = Parrot_str_byte_length(INTERP, string_result);
-        GET_ATTR_read_offset(INTERP, SELF, offset);
-        newline_pos = Parrot_str_find_index(INTERP, string_result, CONST_STRING(INTERP, "\n"), offset);
-
-        /* No newline found, read the rest of the string. */
-        if (newline_pos == -1)
-            read_length = orig_length - offset;
-        else
-            read_length = newline_pos - offset + 1; /* +1 to include the newline */
-
-        string_result = Parrot_str_substr(INTERP, string_result, offset,
-                read_length, NULL, 0);
-        SET_ATTR_read_offset(INTERP, SELF, newline_pos + 1);
-
+        string_result = Parrot_io_readline(INTERP, SELF);
         RETURN(STRING *string_result);
     }
 
@@ -393,7 +344,7 @@
 */
 
     METHOD flush() {
-        SET_ATTR_stringhandle(INTERP, SELF, NULL);
+        Parrot_io_flush(INTERP, SELF);
     }
 
 /*

Modified: trunk/t/native_pbc/annotations.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/integer_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/integer_4.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_2.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_4.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_5.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/string_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/string_4.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/op/interp.t
==============================================================================
--- trunk/t/op/interp.t	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/t/op/interp.t	Tue Jun  9 15:07:24 2009	(r39472)
@@ -56,13 +56,6 @@
     print "uno\n"
     runinterp test_interp, pasm
     print "dos\n"
-
-  get_stdout:
-    $S0 = readline stdout
-    actual .= $S0
-    if $S0 goto get_stdout
-
-    print actual
     goto pasm_end
 
   pasm:

Modified: trunk/t/pmc/io.t
==============================================================================
--- trunk/t/pmc/io.t	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/t/pmc/io.t	Tue Jun  9 15:07:24 2009	(r39472)
@@ -7,7 +7,7 @@
 use lib qw( . lib ../lib ../../lib );
 
 use Test::More;
-use Parrot::Test tests => 42;
+use Parrot::Test tests => 41;
 use Parrot::Test::Util 'create_tempfile';
 use Parrot::Test::Util 'create_tempfile';
 
@@ -39,58 +39,6 @@
     close $FOO;
 }
 
-TODO: {
-    local $TODO = "IO on some invalid types";
-
-    pir_output_is( <<'CODE', <<'OUTPUT', "IO on some invalid types" );
-.sub main
-    $P0 = null
-    test($P0, "Undef")
-    new $P0, ['Integer']
-    test($P0, "null")
-    new $P0, ['Undef']
-    test($P0, "Integer")
-    new $P0, ['String']
-    test($P0, "String")
-.end
-.sub test
-    .param pmc io
-    .param string name
-
-    print name
-    read $S0, io, 1
-    length $I0, $S0
-    if $I0 == 0 goto ok1
-    print " not"
-ok1:
-    print " ok 1\n"
-
-    print name
-    # what should happen here?
-    close io
-    print " ok 2\n"
-
-    print name
-    # what should happen here?
-    print io, "not"
-    print " ok 3\n"
-.end
-CODE
-Undef ok 1
-Undef ok 2
-Undef ok 3
-null ok 1
-null ok 2
-null ok 3
-Integer ok 1
-Integer ok 2
-Integer ok 3
-String ok 1
-String ok 2
-String ok 3
-OUTPUT
-}
-
 my (undef, $temp_file) = create_tempfile( UNLINK => 1 );
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "open/close" );

Modified: trunk/t/pmc/pmc.t
==============================================================================
--- trunk/t/pmc/pmc.t	Tue Jun  9 09:27:14 2009	(r39471)
+++ trunk/t/pmc/pmc.t	Tue Jun  9 15:07:24 2009	(r39472)
@@ -49,7 +49,7 @@
 my $checkTypes;
 my %types_we_cant_test
     = map { $_ => 1; } (    # These require initializers.
-    qw(default Null Iterator Enumerate ParrotObject ParrotThread BigInt LexInfo LexPad Object),
+    qw(default Null Iterator Enumerate ParrotObject ParrotThread BigInt LexInfo LexPad Object Handle),
 
     # Instances of these appear to have other types.
     qw(PMCProxy Class) );


More information about the parrot-commits mailing list