From 6165c935d3f8e591547c10eaf2b00ac788b0a45c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 16 Aug 2004 23:29:07 +0000 Subject: [PATCH] no longer try using the same port for reading and writing --- TODO.FACTOR.txt | 7 +- doc/devel-guide.tex | 95 +++++++++++++++++-- library/cross-compiler.factor | 1 - library/image.factor | 1 - library/init.factor | 1 - library/inspect-vocabularies.factor | 3 +- library/inspector.factor | 1 - library/jedit/jedit.factor | 2 +- library/platform/jvm/compiler.factor | 1 - library/platform/jvm/cross-compiler.factor | 1 - library/platform/jvm/prettyprint.factor | 1 - library/platform/jvm/vocabularies.factor | 2 +- library/platform/jvm/words.factor | 1 - library/platform/native/init.factor | 1 - library/platform/native/io-internals.factor | 2 +- library/platform/native/parse-numbers.factor | 1 - library/platform/native/parse-syntax.factor | 1 - library/platform/native/parser.factor | 1 - library/platform/native/prettyprint.factor | 1 - library/platform/native/stream.factor | 8 +- library/platform/native/unparser.factor | 1 - library/platform/native/vocabularies.factor | 3 +- library/platform/native/words.factor | 1 - library/prettyprint.factor | 1 - library/stdio.factor | 11 ++- library/stream.factor | 1 - library/test/inspector.factor | 2 +- .../test/jvm-compiler/miscellaneous.factor | 1 - library/test/namespaces/java.factor | 1 - library/test/namespaces/namespaces.factor | 1 - library/test/prettyprint.factor | 2 +- library/test/test.factor | 1 - library/vocabularies.factor | 5 +- library/vocabulary-style.factor | 4 +- native/fd.c | 19 ++-- native/file.c | 3 +- native/iomux.c | 17 +++- native/port.c | 34 ++----- native/port.h | 11 +-- native/socket.c | 13 +-- 40 files changed, 157 insertions(+), 107 deletions(-) diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index c9d0d8583b..5baa00f7df 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -1,13 +1,11 @@ 0.62: -- stdout hangs - read-line: handle \r\n -- flush output buffer before reading line -- print: only flush in stdio stream - ignore errors from flush - can-read-line? -- EOF in client connections - vector-each/map examples +- unparse examples +- finish second practical - sbuf-hashcode - vector-hashcode - listener backspace overzealous @@ -52,7 +50,6 @@ - read# - to_fixnum and friends: error on float -ERROR: I/O error: [ "primitive_read_line_fd_8" "Resource temporarily unavailable" ] - parsing should be parsing - describe-word - contains ==> contains? diff --git a/doc/devel-guide.tex b/doc/devel-guide.tex index 967c85e263..f8fab4b35a 100644 --- a/doc/devel-guide.tex +++ b/doc/devel-guide.tex @@ -1167,7 +1167,7 @@ Vectors are applicable to a different class of problems than lists. Compare the relative performance of common operations on vectors and lists: -\begin{tabular}{|c|c|c|} +\begin{tabular}{|r|l|l|} \hline & Lists& @@ -1298,7 +1298,7 @@ can write: Other special characters, such as quotes and tabs can be input in a similar manner. Here is the full list of supported character escapes: -\begin{tabular}{|c|c|} +\begin{tabular}{|r|l|} \hline Character& Escape\tabularnewline @@ -1773,6 +1773,25 @@ Reading a number, showing a menu \subsection{The name stack} +So far, we have seen what we called ``the stack'' store intermediate values between computations. In fact Factor maintains a number of other stacks, and the formal name for the stack we've been dealing with so far is the \emph{data stack}. + +Another stack is the \emph{call stack}. When a colon definition is invoked, the position within the current colon definition is pushed on the stack. This ensures that calling words return to the caller, just as in any other language with subroutines.\footnote{Factor supports a variety of structures for implementing non-local word exits, such as exceptions, co-routines, continuations, and so on. They all rely on manipulating the call stack and are described in later sections.} + +The \emph{name stack} is the focus of this section. The \texttt{bind} combinator creates dynamic scope by pushing and popping namespaces on the name stack. Its definition is simpler than one would expect: + +\begin{alltt} +: bind ( namespace quot -- ) + swap >n call n> drop ; +\end{alltt} + +The words \texttt{>n} and \texttt{n>} push and pop the name stack, respectively. Observe the stack flow in the definition of \texttt{bind}; the namespace goes on the name stack, the quotation is called, and the name space is popped and discarded. + +The name stack is really just a vector. The words \texttt{>n} and \texttt{n>} are implemented as follows: + +\begin{alltt} +: >n ( namespace -- n:namespace ) namestack* vector-push ; +: n> ( n:namespace -- namespace ) namestack* vector-pop ; +\end{alltt} \subsection{The inspector} @@ -1780,15 +1799,75 @@ Reading a number, showing a menu \section{PRACTICAL: Music player} -\section{Deeper in the beast} +\section{Metaprogramming} -Text -> objects - parser, objects -> text - unparser for atoms, prettyprinter -for collections. +Recall that code quotations are in fact just linked lists. Factor code is data, and vice versa. Essentially, the interpreter iterates through code quotations, pushing literals and executing words. When a word is executed, one of two things happen -- either the word has a colon definition, and the interpreter is invoked recursively on the definition, or the word is primitive, and it is executed by the underlying virtual machine. A word is itself a first-class object. -What really is a word -- primitive, parameter, property list. +It is the job of the parser to transform source code denoting literals and words into their internal representations. This is done using a vocabulary of \emph{parsing words}. The prettyprinter does the converse, by printing out data structures in a parsable form (both to humans and Factor). Because code is data, text representation of source code doubles as a way to serialize almost any Factor object. -Call stack how it works and >r/r> +\subsection{Looking at words} +Try pushing a list of words on the stack, and take its first element: + +\begin{alltt} +{[} * + {]} car .s +\emph{\{ * \}} +\end{alltt} + +What happened here? Instead of being executed, a ``naked'', unquoted word was pushed on the stack. The predicate \texttt{word? ( obj -{}- ? )} from the \texttt{words} vocabulary tests if the top of the stack is a word. Another way to get a word on the stack is to do a vocabulary search using a word name and a list of vocabularies to search in: + +\begin{alltt} +"car" {[} "lists" {]} search .s +\emph{\{ car \}} +\end{alltt} + +The \texttt{search} word will push \texttt{f} if the word is not defined. A new word can be created in a specified vocabulary explicitly: + +\begin{alltt} +"start-server" "user" create .s +\emph{\{ start-server \}} +\end{alltt} + +Two words are only ever equal under the \texttt{=} operator if they identify the same underlying object. Word objects are composed of three slots, named as follows. + +\begin{tabular}{|r|l|} +\hline +Slot& +Description\tabularnewline +\hline +\hline +Primitive& +A number identifying a virtual machine operation.\tabularnewline +\hline +Parameter& +An object parameter for the virtual machine operation.\tabularnewline +\hline +Property list& +An association list of name/value pairs.\tabularnewline +\hline +\end{tabular} + +If the primitive number is set to 1, the word is a colon definition and the parameter must be a quotation. Any other primitive number denotes a function of the virtual machine, and the parameter is ignored. Do not rely on primitive numbers in your code, instead use the \texttt{compound? ( obj -{}- ? )} and \texttt{primitive? ( obj -{}- ? )} predicates. + +The word \texttt{define ( word quot -{}- )} defines a word to have the specified colon definition. Note that \texttt{create} and \texttt{define} perform an action somewhat analagous to the \texttt{: ... ;} notation for colon definitions, except at parse time rather than run time. + +\subsection{The prettyprinter} + +We've already seen the word \texttt{.} which prints the top of the stack in a form that may be read back in. The word \texttt{prettyprint} is similar, except the output is in an indented, multiple-line format. Both words are in the \texttt{prettyprint} vocabulary. Here is an example: + +\begin{alltt} +{[} 1 {[} 2 3 4 {]} 5 {]} . +\emph{{[} 1 {[} 2 3 4 {]} 5 {]}} +{[} 1 {[} 2 3 4 {]} 5 {]} prettyprint +\emph{{[} + 1 {[} + 2 3 4 + {]} 5 +{]}} +\end{alltt} + + +\subsection{The parser} \subsection{Parsing words} @@ -1864,6 +1943,8 @@ types of objects. Strings are covered in great detail later. \section{Continuations} +Call stack how it works and >r/r> + Generators, co-routines, multitasking, exception handling diff --git a/library/cross-compiler.factor b/library/cross-compiler.factor index d586d79ef8..124c5a8f21 100644 --- a/library/cross-compiler.factor +++ b/library/cross-compiler.factor @@ -38,7 +38,6 @@ USE: streams USE: strings USE: vectors USE: vectors -USE: vocabularies USE: words IN: arithmetic diff --git a/library/image.factor b/library/image.factor index 946999047b..05a0816714 100644 --- a/library/image.factor +++ b/library/image.factor @@ -42,7 +42,6 @@ USE: streams USE: strings USE: test USE: vectors -USE: vocabularies USE: unparser USE: words diff --git a/library/init.factor b/library/init.factor index 2480c2c686..472baf92bc 100644 --- a/library/init.factor +++ b/library/init.factor @@ -42,7 +42,6 @@ USE: stdio USE: streams USE: strings USE: words -USE: vocabularies ! This file is run as the last stage of boot.factor; it relies ! on all other words already being defined. diff --git a/library/inspect-vocabularies.factor b/library/inspect-vocabularies.factor index d204d60487..9956eea3d0 100644 --- a/library/inspect-vocabularies.factor +++ b/library/inspect-vocabularies.factor @@ -25,7 +25,7 @@ ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -IN: vocabularies +IN: words USE: combinators USE: inspector USE: lists @@ -36,7 +36,6 @@ USE: stack USE: stdio USE: strings USE: unparser -USE: words : word-uses? ( of in -- ? ) 2dup = [ diff --git a/library/inspector.factor b/library/inspector.factor index d9cb269123..f7a2268288 100644 --- a/library/inspector.factor +++ b/library/inspector.factor @@ -40,7 +40,6 @@ USE: words USE: prettyprint USE: unparser USE: vectors -USE: vocabularies : relative>absolute-object-path ( string -- string ) "object-path" get [ "'" rot cat3 ] when* ; diff --git a/library/jedit/jedit.factor b/library/jedit/jedit.factor index 48fbfe3950..8f3bf28567 100644 --- a/library/jedit/jedit.factor +++ b/library/jedit/jedit.factor @@ -31,7 +31,7 @@ USE: combinators USE: namespaces USE: stack USE: strings -USE: vocabularies +USE: words : view ( -- view ) [ ] "org.gjt.sp.jedit.jEdit" diff --git a/library/platform/jvm/compiler.factor b/library/platform/jvm/compiler.factor index e0e3bbf7d0..c13e68d460 100644 --- a/library/platform/jvm/compiler.factor +++ b/library/platform/jvm/compiler.factor @@ -32,7 +32,6 @@ USE: namespaces USE: stack USE: stdio USE: words -USE: vocabularies : class-name ( class -- name ) [ ] "java.lang.Class" "getName" jinvoke ; diff --git a/library/platform/jvm/cross-compiler.factor b/library/platform/jvm/cross-compiler.factor index 34b3295228..aeaea0957b 100644 --- a/library/platform/jvm/cross-compiler.factor +++ b/library/platform/jvm/cross-compiler.factor @@ -36,7 +36,6 @@ USE: streams USE: strings USE: vectors USE: vectors -USE: vocabularies USE: words : worddef, ( word -- ) diff --git a/library/platform/jvm/prettyprint.factor b/library/platform/jvm/prettyprint.factor index d32e5c40bc..f52245b795 100644 --- a/library/platform/jvm/prettyprint.factor +++ b/library/platform/jvm/prettyprint.factor @@ -33,7 +33,6 @@ USE: prettyprint USE: stack USE: stdio USE: unparser -USE: vocabularies USE: words : prettyprint-~<< ( indent -- indent ) diff --git a/library/platform/jvm/vocabularies.factor b/library/platform/jvm/vocabularies.factor index f226d9eaa1..22b6c488a4 100644 --- a/library/platform/jvm/vocabularies.factor +++ b/library/platform/jvm/vocabularies.factor @@ -25,7 +25,7 @@ ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -IN: vocabularies +IN: words USE: combinators USE: kernel USE: lists diff --git a/library/platform/jvm/words.factor b/library/platform/jvm/words.factor index f8a8485459..ee95e04962 100644 --- a/library/platform/jvm/words.factor +++ b/library/platform/jvm/words.factor @@ -32,7 +32,6 @@ USE: lists USE: logic USE: namespaces USE: stack -USE: vocabularies : worddef? ( obj -- boolean ) "factor.FactorWordDefinition" is ; diff --git a/library/platform/native/init.factor b/library/platform/native/init.factor index d65d6eab33..d923d2a44d 100644 --- a/library/platform/native/init.factor +++ b/library/platform/native/init.factor @@ -48,7 +48,6 @@ USE: streams USE: strings USE: styles USE: vectors -USE: vocabularies USE: words USE: unparser diff --git a/library/platform/native/io-internals.factor b/library/platform/native/io-internals.factor index 9535d8160c..b7c8facb9b 100644 --- a/library/platform/native/io-internals.factor +++ b/library/platform/native/io-internals.factor @@ -60,6 +60,6 @@ USE: strings : wait-to-accept ( socket -- ) [ swap add-accept-io-task next-io-task drop ( call ) ] callcc0 ; -: blocking-accept ( socket -- host port socket ) +: blocking-accept ( socket -- host port in out ) dup wait-to-accept accept-fd ; diff --git a/library/platform/native/parse-numbers.factor b/library/platform/native/parse-numbers.factor index 1dff71ba8c..e887fc5d95 100644 --- a/library/platform/native/parse-numbers.factor +++ b/library/platform/native/parse-numbers.factor @@ -36,7 +36,6 @@ USE: namespaces USE: stack USE: strings USE: words -USE: vocabularies USE: unparser ! Number parsing diff --git a/library/platform/native/parse-syntax.factor b/library/platform/native/parse-syntax.factor index 339862cb21..1562c49665 100644 --- a/library/platform/native/parse-syntax.factor +++ b/library/platform/native/parse-syntax.factor @@ -42,7 +42,6 @@ USE: stack USE: strings USE: words USE: vectors -USE: vocabularies USE: unparser ! Constants diff --git a/library/platform/native/parser.factor b/library/platform/native/parser.factor index 8fce63dbe8..699969c146 100644 --- a/library/platform/native/parser.factor +++ b/library/platform/native/parser.factor @@ -36,7 +36,6 @@ USE: namespaces USE: stack USE: strings USE: words -USE: vocabularies USE: unparser ! The parser uses a number of variables: diff --git a/library/platform/native/prettyprint.factor b/library/platform/native/prettyprint.factor index 4f4789139e..837ec50088 100644 --- a/library/platform/native/prettyprint.factor +++ b/library/platform/native/prettyprint.factor @@ -32,7 +32,6 @@ USE: prettyprint USE: stack USE: stdio USE: unparser -USE: vocabularies USE: words : see-compound ( word -- ) diff --git a/library/platform/native/stream.factor b/library/platform/native/stream.factor index e8173d8b11..4cfc32c2fd 100644 --- a/library/platform/native/stream.factor +++ b/library/platform/native/stream.factor @@ -61,10 +61,10 @@ USE: namespaces ] extend ; : ( path -- stream ) - t f open-file f ; + t f open-file ; : ( path -- stream ) - f t open-file f swap ; + f t open-file ; : ( path -- stream ) ; @@ -83,8 +83,8 @@ USE: namespaces [ "socket" get close-fd ] "fclose" set ] extend ; -: ( host port socket -- stream ) - dup [ "port" set "client" set ] extend ; +: ( host port in out -- stream ) + [ "port" set "client" set ] extend ; : accept ( server -- client ) #! Accept a connection from a server socket. diff --git a/library/platform/native/unparser.factor b/library/platform/native/unparser.factor index 93e3a466d2..d2da4e845d 100644 --- a/library/platform/native/unparser.factor +++ b/library/platform/native/unparser.factor @@ -38,7 +38,6 @@ USE: stack USE: stdio USE: strings USE: words -USE: vocabularies : integer% ( num -- ) "base" get /mod swap dup 0 > [ diff --git a/library/platform/native/vocabularies.factor b/library/platform/native/vocabularies.factor index 6299670228..e9030a896b 100644 --- a/library/platform/native/vocabularies.factor +++ b/library/platform/native/vocabularies.factor @@ -25,11 +25,10 @@ ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -IN: vocabularies +IN: words USE: lists USE: namespaces USE: stack -USE: words : (search) ( name vocab -- word ) vocab dup [ get* ] [ 2drop f ] ifte ; diff --git a/library/platform/native/words.factor b/library/platform/native/words.factor index 74f374eb3c..0891716cbd 100644 --- a/library/platform/native/words.factor +++ b/library/platform/native/words.factor @@ -32,7 +32,6 @@ USE: lists USE: logic USE: namespaces USE: stack -USE: vocabularies : word-property ( pname word -- pvalue ) word-plist assoc ; diff --git a/library/prettyprint.factor b/library/prettyprint.factor index 7e0137ad12..c28c311e18 100644 --- a/library/prettyprint.factor +++ b/library/prettyprint.factor @@ -41,7 +41,6 @@ USE: strings USE: styles USE: unparser USE: vectors -USE: vocabularies USE: words : tab-size diff --git a/library/stdio.factor b/library/stdio.factor index 69cd7f362a..9be48a6121 100644 --- a/library/stdio.factor +++ b/library/stdio.factor @@ -35,7 +35,16 @@ USE: streams : ( stream -- stream ) #! We disable fclose on stdio so that various tricks like #! with-stream can work. - clone [ [ ] "fclose" set ] extend ; + clone [ + ( string -- ) + [ + namespace fwrite + "\n" namespace fwrite + namespace fflush + ] "fprint" set + + [ ] "fclose" set + ] extend ; : flush ( -- ) "stdio" get fflush ; diff --git a/library/stream.factor b/library/stream.factor index cc366755ae..7597cc588a 100644 --- a/library/stream.factor +++ b/library/stream.factor @@ -81,7 +81,6 @@ USE: strings [ namespace fwrite "\n" namespace fwrite - namespace fflush ] "fprint" set ] extend ; diff --git a/library/test/inspector.factor b/library/test/inspector.factor index 2316bcf5bf..63983a2cf5 100644 --- a/library/test/inspector.factor +++ b/library/test/inspector.factor @@ -1,7 +1,7 @@ IN: scratchpad USE: inspector USE: namespaces -USE: vocabularies +USE: words "httpd" apropos. "car" usages. diff --git a/library/test/jvm-compiler/miscellaneous.factor b/library/test/jvm-compiler/miscellaneous.factor index e8c90d6cc6..c561e9e59c 100644 --- a/library/test/jvm-compiler/miscellaneous.factor +++ b/library/test/jvm-compiler/miscellaneous.factor @@ -12,7 +12,6 @@ USE: stack USE: stdio USE: strings USE: test -USE: vocabularies USE: words "Checking dictionary words." print diff --git a/library/test/namespaces/java.factor b/library/test/namespaces/java.factor index 0a37e5a127..0b99922330 100644 --- a/library/test/namespaces/java.factor +++ b/library/test/namespaces/java.factor @@ -6,7 +6,6 @@ USE: namespaces USE: stack USE: test USE: words -USE: vocabularies [ [ 1 0 0 0 ] ] [ [ >n ] ] [ balance>list ] test-word [ [ 1 1 0 0 ] ] [ [ get ] ] [ balance>list ] test-word diff --git a/library/test/namespaces/namespaces.factor b/library/test/namespaces/namespaces.factor index 7b048f20b1..1fe8d28651 100644 --- a/library/test/namespaces/namespaces.factor +++ b/library/test/namespaces/namespaces.factor @@ -4,7 +4,6 @@ USE: namespaces USE: test USE: stack USE: words -USE: vocabularies "test-namespace" set diff --git a/library/test/prettyprint.factor b/library/test/prettyprint.factor index c3933c00b8..ada973ad01 100644 --- a/library/test/prettyprint.factor +++ b/library/test/prettyprint.factor @@ -2,6 +2,6 @@ IN: scratchpad USE: lists USE: prettyprint USE: test -USE: vocabularies +USE: words [ vocabs [ words [ see ] each ] each ] time diff --git a/library/test/test.factor b/library/test/test.factor index 49fea26160..a8004ab90d 100644 --- a/library/test/test.factor +++ b/library/test/test.factor @@ -17,7 +17,6 @@ USE: stdio USE: strings USE: words USE: unparser -USE: vocabularies : assert ( t -- ) [ "Assertion failed!" throw ] unless ; diff --git a/library/vocabularies.factor b/library/vocabularies.factor index 28d07718c0..edf41792ba 100644 --- a/library/vocabularies.factor +++ b/library/vocabularies.factor @@ -25,7 +25,7 @@ ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -IN: vocabularies +IN: words USE: combinators USE: kernel USE: lists @@ -57,7 +57,8 @@ USE: strings : words ( vocab -- list ) #! Push a list of all words in a vocabulary. - vocab [ values ] bind ; + #! Filter empty slots. + vocab [ values ] bind [ ] subset ; : intern ( "word" -- word ) #! Returns the top of the stack if it already been interned. diff --git a/library/vocabulary-style.factor b/library/vocabulary-style.factor index fe4bb40547..1724a70e81 100644 --- a/library/vocabulary-style.factor +++ b/library/vocabulary-style.factor @@ -25,15 +25,13 @@ ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -IN: vocabularies +IN: words USE: combinators USE: lists USE: kernel USE: namespaces USE: stack USE: styles -USE: vocabularies -USE: words : get-vocab-style ( vocab -- style ) #! Each vocab has a style object specifying how words are diff --git a/native/fd.c b/native/fd.c index 8fab55b72f..310114b447 100644 --- a/native/fd.c +++ b/native/fd.c @@ -2,9 +2,8 @@ void init_io(void) { - env.user[STDIN_ENV] = tag_object(port(0)); - env.user[STDOUT_ENV] = tag_object(port(1)); - env.user[STDERR_ENV] = tag_object(port(2)); + env.user[STDIN_ENV] = tag_object(port(PORT_READ,0)); + env.user[STDOUT_ENV] = tag_object(port(PORT_WRITE,1)); } bool can_read_line(PORT* port) @@ -98,13 +97,11 @@ bool can_write(PORT* port, FIXNUM len) { CELL buf_capacity; - switch(port->buf_mode) + switch(port->type) { - case B_NONE: - return true; - case B_READ_LINE: + case PORT_READ: return false; - case B_WRITE: + case PORT_WRITE: buf_capacity = port->buffer->capacity * CHARS; /* Is the string longer than the buffer? */ if(port->buf_fill == 0 && len > buf_capacity) @@ -116,7 +113,7 @@ bool can_write(PORT* port, FIXNUM len) else return (port->buf_fill + len <= buf_capacity); default: - critical_error("Bad buf_mode",port->buf_mode); + critical_error("Bad port->type",port->type); return false; } } @@ -135,8 +132,6 @@ void write_fd_char_8(PORT* port, FIXNUM ch) if(!can_write(port,1)) io_error(port,__FUNCTION__); - init_buffer(port,B_WRITE); - bput((CELL)port->buffer + sizeof(STRING) + port->buf_fill,c); port->buf_fill++; } @@ -149,8 +144,6 @@ void write_fd_string_8(PORT* port, STRING* str) if(!can_write(port,str->capacity)) io_error(port,__FUNCTION__); - init_buffer(port,B_WRITE); - c_str = to_c_string(str); /* Append string to buffer */ diff --git a/native/file.c b/native/file.c index 131a0cce2c..74d786a5d9 100644 --- a/native/file.c +++ b/native/file.c @@ -21,5 +21,6 @@ void primitive_open_file(void) if(fd < 0) io_error(NULL,__FUNCTION__); - dpush(tag_object(port(fd))); + dpush(read ? tag_object(port(PORT_READ,fd)) : F); + dpush(write ? tag_object(port(PORT_WRITE,fd)) : F); } diff --git a/native/iomux.c b/native/iomux.c index 3c0061f570..43651c41f7 100644 --- a/native/iomux.c +++ b/native/iomux.c @@ -111,7 +111,11 @@ bool set_up_fd_set(fd_set* fdset, int fd_count, IO_TASK* io_tasks) bool perform_read_line_io_task(PORT* port) { - init_buffer(port,B_READ_LINE); + if(port->line == F) + port->line = tag_object(sbuf(LINE_SIZE)); + else + untag_sbuf(port->line)->top = 0; + if(port->buf_pos >= port->buf_fill) { if(!read_step(port)) @@ -130,7 +134,6 @@ bool perform_read_line_io_task(PORT* port) bool perform_write_io_task(PORT* port) { - init_buffer(port,B_WRITE); if(write_step(port)) { if(port->buf_pos == port->buf_fill) @@ -243,7 +246,15 @@ CELL next_io_task(void) void primitive_next_io_task(void) { - dpush(next_io_task()); + CELL callback; + for(;;) + { + callback = next_io_task(); + if(callback != F) + break; + } + + dpush(callback); } void collect_io_tasks(void) diff --git a/native/port.c b/native/port.c index 6a921648c3..92b47eaed0 100644 --- a/native/port.c +++ b/native/port.c @@ -11,19 +11,25 @@ PORT* untag_port(CELL tagged) return p; } -PORT* port(CELL fd) +PORT* port(PORT_MODE type, CELL fd) { PORT* port = allot_object(PORT_TYPE,sizeof(PORT)); + port->type = type; port->fd = fd; port->buffer = NULL; port->line = F; port->client_host = F; port->client_port = F; port->client_socket = F; - port->buf_mode = B_NONE; + port->line = F; port->buf_fill = 0; port->buf_pos = 0; + if(type == PORT_SPECIAL) + port->buffer = NULL; + else + port->buffer = string(BUF_SIZE,'\0'); + if(fcntl(port->fd,F_SETFL,O_NONBLOCK,1) == -1) io_error(port,__FUNCTION__); @@ -35,28 +41,6 @@ void primitive_portp(void) drepl(tag_boolean(typep(PORT_TYPE,dpeek()))); } -void init_buffer(PORT* port, int mode) -{ - if(port->buf_mode == B_NONE) - port->buffer = string(BUF_SIZE,'\0'); - - if(port->buf_mode != mode) - { - port->buf_fill = port->buf_pos = 0; - port->buf_mode = mode; - - if(mode == B_READ_LINE) - port->line = tag_object(sbuf(LINE_SIZE)); - } - else if(port->buf_mode == B_READ_LINE) - { - if(port->line == F) - port->line = tag_object(sbuf(LINE_SIZE)); - else - untag_sbuf(port->line)->top = 0; - } -} - void fixup_port(PORT* port) { port->fd = -1; @@ -65,7 +49,6 @@ void fixup_port(PORT* port) fixup(&port->line); fixup(&port->client_host); fixup(&port->client_port); - fixup(&port->client_socket); } void collect_port(PORT* port) @@ -75,5 +58,4 @@ void collect_port(PORT* port) copy_object(&port->line); copy_object(&port->client_host); copy_object(&port->client_port); - copy_object(&port->client_socket); } diff --git a/native/port.h b/native/port.h index ca7bc65391..34f445861a 100644 --- a/native/port.h +++ b/native/port.h @@ -1,8 +1,9 @@ -/* Buffer mode */ -typedef enum { B_READ_LINE, B_WRITE, B_NONE } B_MODE; +typedef enum { PORT_READ, PORT_WRITE, PORT_SPECIAL } PORT_MODE; typedef struct { CELL header; + /* one of PORT_READ or PORT_WRITE */ + PORT_MODE type; FIXNUM fd; STRING* buffer; /* tagged partial line used by read_line_fd */ @@ -10,9 +11,8 @@ typedef struct { /* tagged client info used by accept_fd */ CELL client_host; CELL client_port; + /* untagged fd of accepted connection */ CELL client_socket; - /* one of B_READ, B_WRITE or B_NONE */ - B_MODE buf_mode; /* top of buffer */ CELL buf_fill; /* current read/write position */ @@ -20,8 +20,7 @@ typedef struct { } PORT; PORT* untag_port(CELL tagged); -PORT* port(CELL fd); -void init_buffer(PORT* port, int mode); +PORT* port(PORT_MODE type, CELL fd); void primitive_portp(void); void fixup_port(PORT* port); void collect_port(PORT* port); diff --git a/native/socket.c b/native/socket.c index eedef4291b..643027a95d 100644 --- a/native/socket.c +++ b/native/socket.c @@ -40,7 +40,7 @@ int make_server_socket(CHAR port) void primitive_server_socket(void) { CHAR p = (CHAR)to_fixnum(dpop()); - dpush(tag_object(port(make_server_socket(p)))); + dpush(tag_object(port(PORT_SPECIAL,make_server_socket(p)))); } CELL accept_connection(PORT* p) @@ -60,15 +60,16 @@ CELL accept_connection(PORT* p) p->client_host = tag_object(from_c_string(inet_ntoa( clientname.sin_addr))); p->client_port = tag_fixnum(ntohs(clientname.sin_port)); - p->client_socket = tag_object(port(new)); + p->client_socket = new; return true; } void primitive_accept_fd(void) { - PORT* port = untag_port(dpop()); - dpush(port->client_host); - dpush(port->client_port); - dpush(port->client_socket); + PORT* p = untag_port(dpop()); + dpush(p->client_host); + dpush(p->client_port); + dpush(tag_object(port(PORT_READ,p->client_socket))); + dpush(tag_object(port(PORT_WRITE,p->client_socket))); }