* libguile/ports.c (scm_i_write_bytes_unlocked): Allow incomplete
writes from the implementation.
(scm_c_write_bytes_unlocked): Use scm_i_write_bytes_unlocked helper to
call the write function.
* libguile/r6rs-ports.c (custom_binary_output_port_write): Don't loop;
core Guile will do that.
This will allow better Scheme integration for ports.
* libguile/ports.h (scm_t_port_buffer): Change "holder" member to be a
bytevector defined to have "buf" as its starting point.
(scm_t_ptob_descriptor): Change read and write functions to take
bytevectors as arguments and to return the number of octets read or
written.
(scm_make_port_type): Adapt accordingly.
(scm_c_read_bytes, scm_c_write_bytes): New functions that take
bytevectors.
* libguile/ports.c (scm_make_port_type): Adapt to read/write function
prototype change.
(scm_c_make_port_buffer): Arrange to populate the "bytevector" field.
(scm_i_read_bytes_unlocked): New function.
(scm_i_read_unlocked): Use scm_i_read_bytes_unlocked.
(scm_c_read_bytes_unlocked): New function.
(scm_c_read_unlocked): Update comment, and always go through the
buffer.
(scm_c_read_bytes): New function.
(scm_flush_unlocked): Use scm_i_write_unlocked instead of the port's
write function.
(scm_i_write_bytes_unlocked): New function.
(scm_i_write_unlocked): Use scm_i_write_bytes_unlocked.
(scm_c_write_bytes_unlocked): New function.
(scm_c_write_unlocked): Always write through the buffer.
(scm_c_write_bytes): New function.
(scm_truncate_file): Remove unused variable.
(void_port_read, void_port_write): Adapt to read/write prototype
change.
* libguile/fports.c (fport_read, fport_write):
* libguile/r6rs-ports.c (bytevector_input_port_read)
(custom_binary_input_port_read, bytevector_output_port_write)
(custom_binary_output_port_write, transcoded_port_write)
(transcoded_port_read): Adapt to read/write prototype
change.
(scm_get_bytevector_n, scm_get_bytevector_n_x)
(scm_get_bytevector_all): Use scm_c_read_bytes.
(scm_put_bytevector): Use scm_c_write_bytes.
* libguile/strports.c (string_port_read, string_port_write):
* libguile/vports.c (soft_port_write, soft_port_read): Adapt to
read/write prototype change.
* test-suite/standalone/test-scm-c-read.c (custom_port_read): Fix for
read API change.
* module/web/http.scm (make-chunked-output-port): Add #:buffering
argument, defaulting to 1200 (some random value under the MTU). This
will force a flush every so often, and not every character as would
otherwise be the case after this port rewrite.
* libguile/ports.h (struct scm_t_port_buffer): New data type.
(struct scm_t_port): Refactor to use port buffers instead of
implementation-managed read and write pointers. Add "read_buffering"
member.
(SCM_INITIAL_PUTBACK_BUF_SIZE, SCM_READ_BUFFER_EMPTY_P): Remove.
(scm_t_ptob_descriptor): Rename "fill_input" function to "read", and
take a port buffer, returning void. Likewise "write" takes a port
buffer and returns void. Remove "end_input"; instead if there is
buffered input and rw_random is true, then there must be a seek
function, so just seek back if needed. Remove "flush"; instead all
calls to the "write" function implicitly include a "flush", since the
buffering happens in the generic port code now. Remove "setvbuf", but
add "get_natural_buffer_sizes"; instead the generic port code can
buffer any port.
(scm_make_port_type): Adapt to read and write prototype changes.
(scm_set_port_flush, scm_set_port_end_input, scm_set_port_setvbuf):
Remove.
(scm_slow_get_byte_or_eof_unlocked)
(scm_slow_get_peek_or_eof_unlocked): Remove; the slow path is to call
scm_fill_input.
(scm_set_port_get_natural_buffer_sizes): New function.
(scm_c_make_port_buffer): New internal function.
(scm_port_non_buffer): Remove. This was a function for
implementations that is no longer needed. Instead open with BUF0 or
use (setvbuf port 'none).
(scm_fill_input, scm_fill_input_unlocked): Return the filled port
buffer.
(scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt
to changes in buffering and EOF management.
* libguile/ports.c: Adapt to port interface changes.
(initialize_port_buffers): New function, using the port mode flags to
set up appropriate initial buffering for all ports.
(scm_c_make_port_with_encoding): Create port buffers here instead of
delegating to implementations.
(scm_close_port): Flush the port if needed instead of delegating to
the implementation.
* libguile/filesys.c (set_element): Adapt to buffering changes.
* libguile/fports.c (fport_get_natural_buffer_sizes): New function,
replacing scm_fport_buffer_add.
(fport_write, fport_read): Update to let the generic ports code do the
buffering.
(fport_flush, fport_end_input): Remove.
(fport_close): Don't flush in a dynwind; that's the core ports' job.
(scm_make_fptob): Adapt.
* libguile/ioext.c (scm_redirect_port): Adapt to buffering changes.
* libguile/poll.c (scm_primitive_poll): Adapt to buffering changes.
* libguile/ports-internal.h (struct scm_port_internal): Remove
pending_eof flag; this is now set on the read buffer.
* libguile/r6rs-ports.c (struct bytevector_input_port): New type. The
new buffering arrangement means that there's now an intermediate
buffer between the bytevector and the user of the port; this could
lead to a perf degradation, but on the other hand there are some other
speedups enabled by the buffering refactor, so probably the memcpy
cost is dwarfed by the cost of the other parts of the ports
machinery.
(make_bytevector_input_port, bytevector_input_port_read):
(bytevector_input_port_seek, initialize_bytevector_input_ports): Adapt
to new buffering arrangement.
(struct custom_binary_port): Remove read buffer, as Guile handles that
now.
(custom_binary_input_port_setvbuf): Remove; now handled by Guile.
(make_custom_binary_input_port, custom_binary_input_port_read)
(initialize_custom_binary_input_ports): Adapt.
(scm_get_bytevector_some): Adapt to new EOF management.
(scm_t_bytevector_output_port_buffer): Hold on to the underlying port,
so we can flush it if it's open.
(make_bytevector_output_port, bytevector_output_port_write):
(bytevector_output_port_seek): Adapt.
(bytevector_output_port_procedure): Flush the port as appropriate, so
that we get all the bytes.
(make_custom_binary_output_port, custom_binary_output_port_write):
Adapt.
(make_transcoded_port): Don't muck with buffering.
(transcoded_port_write): Simply forward the write to the underlying
port.
(transcoded_port_read): Likewise.
(transcoded_port_close): No need to flush.
(initialize_transcoded_ports): Adapt.
* libguile/read.c (scm_i_scan_for_encoding): Adapt to buffering
changes.
* libguile/rw.c (scm_write_string_partial): Adapt to buffering changes.
* libguile/strports.c: Adapt to the fact that we don't manage the
buffer. Probably room for speed improvements here...
* libguile/vports.c (soft_port_get_natural_buffer_sizes): New function.
Adapt the rest of the file for the new buffering regime.
* test-suite/tests/r6rs-ports.test ("8.2.10 Output ports"): Custom
binary output ports need to be flushed before you can rely on the
write! procedure having been called. Add necessary flush-port
invocations.
("8.2.6 Input and output ports"): Transcoded ports now have an
internal buffer by default. This test checks that the characters are
transcoded one at a time, so to do that, call setvbuf on the
transcoded port to remove the buffer.
* test-suite/tests/web-client.test (run-with-http-transcript): Fix for
different flushing regime on soft ports. (The vestigial flush
procedure is now called after each write, which is not what the test
was expecting.)
* test-suite/standalone/test-scm-c-read.c: Update for changes to the C
interface for defining port types.
* doc/ref/api-io.texi (Ports): Update to discuss buffering in a generic
way, and to remove a hand-wavey paragraph describing string ports as
"interesting and powerful".
(Reading, Writing): Remove placeholder comments. Document
`scm_lfwrite'.
(Buffering): New section.
(File Ports): Link to buffering.
(I/O Extensions): Join subnodes into parent and describe new API,
including buffering API.
* doc/ref/posix.texi (Ports and File Descriptors): Link to buffering.
Remove unread-char etc, as they are documented elsewhere.
(Pipes, Network Sockets and Communication): Link to buffering.
* libguile/ports.h (scm_t_ptob_descriptor): The port close function now
returns void.
(scm_set_port_close): Adapt prototype.
* libguile/ports.c (scm_close_port): Always return true if we managed to
call the close function. There's no other sensible result; exceptions
are handled, well, exceptionally.
* libguile/fports.c (fport_close)
* libguile/r6rs-ports.c (custom_binary_port_close, transcoded_port_close):
* libguile/vports.c (soft_port_close): Adapt.
* doc/ref/api-io.texi (Port Implementation): Update.
* libguile/vports.c (struct soft_port): New data structure.
(scm_make_soft_port): Unpack vector into struct when making soft
port.
(soft_port_input_waiting, soft_port_close, soft_port_fill_input):
(soft_port_write, soft_port_flush): Adapt. Remove an extraneous
errno=0 in soft_port_close.
* libguile/poll.c (scm_primitive_poll): A buffered port's buffer marks
it as writable only when writing a byte would not block, which is the
case only if there is more than one byte free in the buffer; writing
the last byte would block.
* libguile/ports.c (scm_seek): Flush before seeking on a buffered port.
* libguile/fports.c (fport_seek):
* libguile/strports.c (st_seek): Remove code to flush buffers.
* test-suite/tests/ports.test: Update test expectations that the
putback buffer is flushed on a seek. Previously there was a special
case for SEEK_CUR with an offset of 0 to avoid flushing buffers, but
that's an arbitrary choice that differs from all other combinations of
OFFSET and WHENCE.
* libguile/fports.c (fport_flush, fport_end_input): Move rw_active
handling to ports.c.
* libguile/ioext.c (scm_redirect_port): Use scm_flush_unlocked instead
of calling the flush function directly.
* libguile/ports.c (scm_c_make_port_with_encoding): Ports default to
"rw_random" mode when they have a seek function.
(scm_c_read_unlocked, scm_i_unget_bytes_unlocked)
(scm_slow_get_byte_or_eof_unlocked)
(scm_slow_peek_byte_or_eof_unlocked): Flush write buffer and set
rw_active always in the same way, and only if rw_random is true.
(scm_end_input_unlocked, scm_flush_unlocked): Clear rw_active here
unconditionally.
(scm_c_write_unlocked): Flush read buffer and set rw_active always in
the same way, but only if rw_random is true.
(scm_c_write, scm_lfwrite): Whitespace fixes.
(scm_lfwrite_substr): Don't flush read buffer; lower-level code will
do this.
(scm_truncate_file): Use scm_flush_unlocked instead of calling the
flush function directly.
* libguile/r6rs-ports.c (transcoded_port_flush): Don't muck with
rw_active.
* libguile/read.c (scm_i_scan_for_encoding): Flush write buffer if
needed in same way as ports.c.
* libguile/strports.c (st_end_input): Don't muck with rw_active.
(scm_mkstrport): rw_random defaults to 1 now.
* libguile/r6rs-ports.c (struct custom_binary_port): Use a struct
instead of a vector as the state for a custom binary port. Adapt all
callers. Some whitespace fixes as well.
* libguile/r6rs-ports.c: Expand out the acronyms "bip", "bop", "cbip",
"cbop", and "tp". They always confused me, especially that the "b" in
cbip/cbop wasn't the same as the one in bip/bop.
* libguile/ports.h (scm_t_port_type_flags): Replace
SCM_PORT_TYPE_HAS_FLUSH with SCM_PORT_TYPE_NEEDS_CLOSE_ON_GC.
(scm_t_ptob_descriptor): Remove free function.
* libguile/ports.c (scm_set_port_needs_close_on_gc): New function.
(scm_set_port_flush): Don't set flags.
(scm_c_make_port_with_encoding, scm_close_port): Use the new flag to
determine when to add a finalizer and also when to include the port in
the weak set.
(scm_set_port_free): Remove.
(do_close, finalize_port): Close port instead of calling free
function.
* libguile/r6rs-ports.c (initialize_transcoded_ports):
* libguile/vports.c (scm_make_sfptob):
* libguile/fports.c (scm_make_fptob): Mark these ports as needing close
on GC.
* libguile/fports.c (fport_free): Remove.
* NEWS: Update.
* doc/ref/api-io.texi (Port Implementation): Update.
* module/language/cps/types.scm (type-entry-saturating-union): Fix range
saturation in the negative direction. Previously we were artificially
truncating negative range ends to zero.
* module/statprof.scm: Remove most of the commentary, as it was
duplicated in the manual and was getting out of date.
(stats): Remove self-secs-per-call and cum-secs-per-call fields as
they can be computed from the other fields.
(statprof-call-data->stats): Adapt.
(statprof-stats-self-secs-per-call):
(statprof-stats-cum-secs-per-call): New functions.
(statprof-display/flat): Don't print the seconds-per-call fields, as
we are no longer stopping the clock around call counters. Anyway
these times were quite misleading.
(with-statprof): Deprecate. It took its keyword arguments at the
beginning; very complicated! Better to use the `statprof' function.
(`statprof' was introduced after `with-statprof' and then
`with-statprof' was adapted to use it.)
* doc/ref/statprof.texi (Statprof): Port this documentation away from
the automatically generated text and update it for the new interfaces
like #:display-style.
* module/system/base/syntax.scm (record-case): Remove comment that
referenced with-statprof. Add comment indicating that record-case
should be replaced.
* doc/ref/scheme-using.texi (Profile Commands): Update to mention
keyword arguments and to link to the statprof documentation.
* module/statprof.scm: Update commentary.
(count-call): Don't bother stopping and starting the timer. The
overhead of call counting perturbs timing too much already, and
somewhat paradoxically stopping and starting the timer takes too much
time.
(skip-count-call): New function.
(stack-samples->procedure-data, stack-samples->callee-lists): If we
are counting calls, skip any part of the stack that is inside
count-call.
* module/system/repl/debug.scm (print-locals): Adapt to
frame-binding-ref change.
* module/system/vm/frame.scm (<binding>): Add `frame' field.
(available-bindings): Capture the frame.
(binding-ref, binding-set!): New functions, accessing a local variable
value directly from a frame.
(frame-binding-ref, frame-binding-set!): Remove. As these are very
low-level debugging interfaces introduced in 2.0, never documented,
and quite tied to the VM, we feel comfortable making this change.
(frame-call-representation): Adapt to available-bindings change.
(frame-environment, frame-object-binding): Adapt to binding-ref
interface change.
* doc/ref/vm.texi (Stack Layout): Mention that slots can be re-used.
Update disassembly in example.
* doc/ref/api-debug.texi (Frames): Remove documentation for
frame-local-ref, frame-local-set!, and frame-num-locals. Replace with
documentation for frame-bindings, binding accessors, and binding-ref /
binding-set!.
* libguile/frames.h (scm_frame_num_locals, scm_frame_local_ref)
(scm_frame_local_set_x): Remove. As long as we are changing the
interface in a backward-incompatible way, we might as well remove
these.
* libguile/frames.c (scm_frame_num_locals, scm_frame_local_ref)
(scm_frame_local_set_x, scm_init_frames_builtins, scm_init_frames):
Arrange to make frame-local-ref et al private to frames.scm.
* module/system/vm/frame.scm: Load scm_init_frames_builtins extensions.
(frame-instruction-pointer-or-primitive-procedure-name): New public
function.
(frame-binding-ref, frame-binding-set!): Allow binding objects as
vars.
* module/system/repl/debug.scm (print-locals): Pass binding directly to
frame-binding-ref.
* module/statprof.scm (sample-stack-procs, count-call): Use new
frame-instruction-pointer-or-primitive-procedure-name function.
* module/system/vm/assembler.scm (define-byte-order-swapper): New
helper.
(byte-swap/2!, byte-swap/4!, byte-swap/8!): New functions.
(link-data): Swap bytes in uniform vectors on foreign byte orders.
* am/bootstrap.am: New file, factored out of bootstrap/Makefile.am.
* bootstrap/Makefile.am: Use bootstrap.am.
* prebuilt/Makefile.am:
* prebuilt/i686-pc-linux-gnu/Makefile.am:
* prebuilt/mips-unknown-linux-gnu/Makefile.am:
* prebuilt/x86_64-unknown-linux-gnu/Makefile.am: New files.
* configure.ac: Output the prebuilt/ makefiles.
* Makefile.am: Descend into prebuilt/ when making dist.
* meta/uninstalled-env.in: Arrange to put prebuilt/ in the beginning of
the GUILE_LOAD_COMPILED_PATH. Also fix a case where bootstrap/ wasn't
being correctly added to the load path.
* module/system/vm/assembler.scm (immediate-bits): Rename from
immediate?, and return the bits. Take asm argument so that we measure
what's an immediate not on the host but for the target. Adapt all
callers.
(write-immediate): Take bits instead of SCM object. Adapt callers.
(write-placeholder): New helper, to write bits for #f. Adapt callers
that wrote #f to use write-placeholder.
* module/statprof.scm (statprof-fetch-call-tree): Add #:precise? keyword
argument, defaulting to false. Search for cycles after computing
printable source locations instead of doing so over addresses -- it
could be that two addresses map to the same source location, and from
the user's perspective they are then indistinguishable in the
printout.
* module/statprof.scm (statprof-display/flat): Rename from
statprof-display. Use real format; we have it.
(statprof-display-anomalies): Likewise use real format.
(procedure=?): Remove unused function.
(collect-cycles): New helper.
(statprof-fetch-call-tree): Fix to root the trees correctly -- it was
interpreting them in the wrong order. Detect cycles so that it's not
so terrible. Use precise locations for source locations. Probably
need to add an option to go back to the per-function behavior.
(statprof-display/tree): New helper, uses statprof-fetch-call-tree to
display a profile in a nested tree.
(statprof-display): Add #:style argument, which can be `flat',
`anomalies', or `tree'.
(statprof): Add #:display-style argument, proxying to #:style,
defaulting to 'flat.
* module/web/http.scm (parse-entity-tag): Be less strict, accepting
unquoted strings as well.
* test-suite/tests/web-http.test ("response headers"): Add a test for
etag parsing.
* module/language/cps/optimize.scm (cps-default-optimization-options):
Add missing #:simplify? option. Otherwise the simplification pass was
running even at -O0.
* bootstrap/Makefile.am: Don't serialize the build through
psyntax-pp.scm. On a multicore make, this will result in higher total
CPU time as multiple processes use an interpreted expander, but lower
total build time, as all processes will take approximately the same
time to load and run the compiler.
* module/language/tree-il/peval.scm (peval): In test context,
fold (let ((x EXP)) (if x x ALT)) to (if EXP #t ALT). This reduces
the number of boolean literals that the compiler has to reify, by
causing EXP to evaluate in test context instead of value context.
Also, rotate `let' out of the test part of conditionals, for the same
reason.
* module/language/cps/simplify.scm (compute-eta-reductions): Eta-reduce
branches as well, so that passing a constant to a branch will fold to
the true or false branch, provided that the test variable was just
used in the branch.
* module/language/cps/reify-primitives.scm (primitive-module): Add cases
for SRFI-4 primitives. These primitives are only treated as such for
the purposes of Tree-IL primitive expansion; perhaps the right fix is
elsewhere, but it's here for now.