diff options
author | Andy Wingo <wingo@pobox.com> | 2017-03-09 17:22:08 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-03-09 17:24:06 +0100 |
commit | c525aa6d95a9e19b260d6b99dbf6d73939d76585 (patch) | |
tree | 579660b1a34b147b3b132b2c64f1e6807dbe3dd5 /module/ice-9 | |
parent | f71c2c12609abfac9af7d38ea99f89a1f51b6992 (diff) |
VM support for string-set!; slimmer read-string
* doc/ref/vm.texi (Inlined Scheme Instructions): Add string-set!.
* libguile/vm-engine.c (string-set!): New opcode.
* module/ice-9/rdelim.scm (read-string): Reimplement in terms of a
geometrically growing list of strings, to reduce total heap usage when
reading big files.
* module/language/cps/compile-bytecode.scm (compile-function): Add
string-set! support.
* module/language/cps/types.scm (string-set!): Update for &u64 index.
* module/language/tree-il/compile-cps.scm (convert): Unbox index to
string-set!.
* module/system/vm/assembler.scm (system): Export string-set!.
Diffstat (limited to 'module/ice-9')
-rw-r--r-- | module/ice-9/rdelim.scm | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/module/ice-9/rdelim.scm b/module/ice-9/rdelim.scm index a406f4e55..d2cd081d7 100644 --- a/module/ice-9/rdelim.scm +++ b/module/ice-9/rdelim.scm @@ -156,13 +156,20 @@ If the COUNT argument is present, treat it as a limit to the number of characters to read. By default, there is no limit." ((#:optional (port (current-input-port))) ;; Fast path. - ;; This creates more garbage than using 'string-set!' as in - ;; 'read-string!', but currently that is faster nonetheless. - (let loop ((chars '())) + (let loop ((head (make-string 30)) (pos 0) (tail '())) (let ((char (read-char port))) - (if (eof-object? char) - (list->string (reverse! chars)) - (loop (cons char chars)))))) + (cond + ((eof-object? char) + (let ((head (substring head 0 pos))) + (if (null? tail) + (substring head 0 pos) + (string-concatenate-reverse tail head pos)))) + (else + (string-set! head pos char) + (if (< (1+ pos) (string-length head)) + (loop head (1+ pos) tail) + (loop (make-string (* (string-length head) 2)) 0 + (cons head tail)))))))) ((port count) ;; Slower path. (let loop ((chars '()) |