the pre scsh static linker
This commit is contained in:
parent
1df0338fb0
commit
3b0a2e2fa5
|
@ -1,303 +0,0 @@
|
||||||
;;; Static heaps for the Scheme Shell
|
|
||||||
;;; Copyright (c) 1994 by Brian D. Carlstrom.
|
|
||||||
|
|
||||||
;;; based on Scheme48 implementation.
|
|
||||||
;;; Copyright (c) 1993, 1994 by Richard Kelsey and Jonathan Rees.
|
|
||||||
|
|
||||||
;;; TODO
|
|
||||||
;;; get it working
|
|
||||||
|
|
||||||
#!
|
|
||||||
,config ,load vm/ps-interface.scm
|
|
||||||
,config ,load vm/interfaces.scm
|
|
||||||
,config ,load vm/package-defs.scm
|
|
||||||
;; Undefined: (pre-scheme vm-utilities system-spec external)
|
|
||||||
,config ,load vm/s48-package-defs.scm
|
|
||||||
|
|
||||||
,load-package bigbit
|
|
||||||
,load-package destructuring
|
|
||||||
|
|
||||||
,load-package heap
|
|
||||||
,in heap
|
|
||||||
(define (newspace-begin) *newspace-begin*)
|
|
||||||
(define (heap-pointer) *hp*)
|
|
||||||
,structure heap-extra (export newspace-begin
|
|
||||||
heap-pointer
|
|
||||||
header-a-units
|
|
||||||
d-vector?
|
|
||||||
stob-type)
|
|
||||||
|
|
||||||
,config
|
|
||||||
(define-structure static (export do-it
|
|
||||||
make-static-heap
|
|
||||||
test)
|
|
||||||
(open scheme heap memory data stob struct
|
|
||||||
heap-extra
|
|
||||||
vm-architecture
|
|
||||||
formats
|
|
||||||
enumerated
|
|
||||||
signals
|
|
||||||
scsh)
|
|
||||||
(files (scsh static)))
|
|
||||||
|
|
||||||
,user
|
|
||||||
,load-package static
|
|
||||||
,open static
|
|
||||||
(test)
|
|
||||||
!#
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
(define *scsh-image* "scsh/scsh.image") ; input file
|
|
||||||
(define *scsh-image* "debug/tiny.image") ; input file
|
|
||||||
(define *image-lib* "scsh.a") ; output file
|
|
||||||
(define *temp-dir* (string-append
|
|
||||||
"/tmp/"
|
|
||||||
"scsh"
|
|
||||||
(number->string
|
|
||||||
(pid)))) ;; prefix for temp files - in their own dir
|
|
||||||
(define *prefix* (string-append *temp-dir* "/"))
|
|
||||||
|
|
||||||
(define (make-static-heap image archive)
|
|
||||||
(if (file-exists? *temp-dir*)
|
|
||||||
(if (equal? 'directory (file-info:type (file-attributes *temp-dir*)))
|
|
||||||
(with-cwd *temp-dir*
|
|
||||||
(map delete-file (directory-files *temp-dir* #t)))
|
|
||||||
(delete-file *temp-dir*)))
|
|
||||||
(create-directory *temp-dir* #o755 #t)
|
|
||||||
(let ((size (file-info:size (file-attributes image))))
|
|
||||||
(do-it size image *prefix*)))
|
|
||||||
|
|
||||||
(define (test)
|
|
||||||
(make-static-heap *scsh-image* *image-lib*))
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; For example:
|
|
||||||
; (do-it 100000 "~/s48/debug/little.image" "little-heap.c")
|
|
||||||
;
|
|
||||||
; The first argument to do-it should be somewhat larger than the size,
|
|
||||||
; in bytes, of the image file to be converted (which you can obtain with
|
|
||||||
; "ls -l").
|
|
||||||
;
|
|
||||||
; If the image contains 0-length stored objects, then the .c file will
|
|
||||||
; have to be compiled by gcc, since 0-length arrays aren't allowed in
|
|
||||||
; ANSI C. This wouldn't be difficult to work around.
|
|
||||||
|
|
||||||
(define *comments?* #f)
|
|
||||||
|
|
||||||
; 800,000 bytes => 200,000 words => at least 100,000 objects
|
|
||||||
; 50 chunks => 16,000 bytes per chunk => 2,000 objects per chunk
|
|
||||||
(define *chunk-size* 10000)
|
|
||||||
|
|
||||||
(define (do-it bytes infile prefix)
|
|
||||||
(let ((start (init bytes infile)))
|
|
||||||
(emit-area-declarations "p" immutable? "const " prefix)
|
|
||||||
(emit-area-declarations "i" mutable? "" prefix)
|
|
||||||
(emit-area-initializers "p" immutable? "const " prefix)
|
|
||||||
(emit-area-initializers "i" mutable? "" prefix)
|
|
||||||
(call-with-output-file (string-append prefix "entry.c")
|
|
||||||
(lambda (port)
|
|
||||||
(display "#include \"" port)
|
|
||||||
(display prefix port)
|
|
||||||
(display (descriptor-include start) port)
|
|
||||||
(display ".h\"" port)
|
|
||||||
(newline port)
|
|
||||||
(display "const long entry = " port)
|
|
||||||
(emit-descriptor start port)
|
|
||||||
(write-char #\; port)
|
|
||||||
(newline port)))))
|
|
||||||
|
|
||||||
(define (init bytes infile)
|
|
||||||
(create-memory (quotient bytes 2) quiescent) ;Output of ls -l
|
|
||||||
(initialize-heap (memory-begin) (memory-size))
|
|
||||||
(let ((start (read-image infile 0)))
|
|
||||||
(let ((n (nchunks)))
|
|
||||||
(message n (if (= n 1) " chunk" " chunks")))
|
|
||||||
start))
|
|
||||||
|
|
||||||
(define (nchunks) (+ (chunk-number (heap-pointer)) 1))
|
|
||||||
|
|
||||||
; emit struct declarations for areas
|
|
||||||
|
|
||||||
(define (emit-area-declarations name in-area? const prefix)
|
|
||||||
(for-each-stored-object
|
|
||||||
(string-append prefix name) ".h"
|
|
||||||
(lambda (chunk port)
|
|
||||||
(message name chunk " declaration")
|
|
||||||
(format port "#define D(x) (long)(&x)+7~%")
|
|
||||||
(format port "#define H unsigned long~%")
|
|
||||||
(display "struct " port) (display name port) (display chunk port)
|
|
||||||
(display " {" port) (newline port))
|
|
||||||
(lambda (x port)
|
|
||||||
(if (in-area? x)
|
|
||||||
(emit-declaration x port)))
|
|
||||||
(lambda (chunk port)
|
|
||||||
(display "};" port)
|
|
||||||
(newline port)
|
|
||||||
(display const port)
|
|
||||||
(display "extern struct " port)
|
|
||||||
(display name port)
|
|
||||||
(display chunk port)
|
|
||||||
(write-char #\space port) (display name port) (display chunk port)
|
|
||||||
(write-char #\; port) (newline port)
|
|
||||||
chunk)))
|
|
||||||
|
|
||||||
(define (emit-declaration x port)
|
|
||||||
(display " H x" port)
|
|
||||||
(writex x port)
|
|
||||||
(cond ((d-vector? x)
|
|
||||||
(display "; long d" port)
|
|
||||||
(writex x port)
|
|
||||||
(write-char #\[ port)
|
|
||||||
(write (d-vector-length x) port))
|
|
||||||
((vm-string? x)
|
|
||||||
(display "; char d" port)
|
|
||||||
(writex x port)
|
|
||||||
(write-char #\[ port)
|
|
||||||
;; Ensure alignment (thanks Ian)
|
|
||||||
(write (cells->bytes (bytes->cells (b-vector-length x)))
|
|
||||||
port))
|
|
||||||
(else
|
|
||||||
(display "; unsigned char d" port)
|
|
||||||
(writex x port)
|
|
||||||
(write-char #\[ port)
|
|
||||||
;; Ensure alignment
|
|
||||||
(write (cells->bytes (bytes->cells (b-vector-length x)))
|
|
||||||
port)))
|
|
||||||
(display "];" port)
|
|
||||||
(if *comments?*
|
|
||||||
(begin (display " /* " port)
|
|
||||||
(display (enumerand->name (stob-type x) stob) port)
|
|
||||||
(display " */" port)))
|
|
||||||
(newline port))
|
|
||||||
|
|
||||||
; Emit initializers for areas
|
|
||||||
|
|
||||||
(define (emit-area-initializers name in-area? const prefix)
|
|
||||||
(for-each-stored-object
|
|
||||||
(string-append prefix name) ".c"
|
|
||||||
(lambda (chunk port)
|
|
||||||
(message name chunk " initializer")
|
|
||||||
(display const port)
|
|
||||||
(display "struct " port) (display name port) (write chunk port)
|
|
||||||
(write-char #\space port) (display name port) (write chunk port)
|
|
||||||
(display " =" port) (newline port)
|
|
||||||
|
|
||||||
(write-char #\{ port) (newline port))
|
|
||||||
(lambda (x port)
|
|
||||||
(if (in-area? x)
|
|
||||||
(emit-initializer x port)))
|
|
||||||
(lambda (chunk port)
|
|
||||||
(display "};" port) (newline port)))
|
|
||||||
|
|
||||||
(call-with-output-file
|
|
||||||
(string-append prefix ".c")
|
|
||||||
(lambda (port)
|
|
||||||
(let ((n (nchunks)))
|
|
||||||
(format port "const long ~a_count = ~s;~%" name n)
|
|
||||||
(format port "~a long * const ~a_areas[~s] = {" const name n)
|
|
||||||
(do ((i 0 (+ i 1)))
|
|
||||||
((= i n))
|
|
||||||
(format port "(~a long *)&~a~s, " const name i))
|
|
||||||
(format port "};~%const long ~a_sizes[~s] = {" name n)
|
|
||||||
(do ((i 0 (+ i 1)))
|
|
||||||
((= i n))
|
|
||||||
(format port "sizeof(~a~s), " name i))
|
|
||||||
(format port "};~%")))))
|
|
||||||
|
|
||||||
|
|
||||||
(define (message . stuff)
|
|
||||||
(for-each display stuff) (newline))
|
|
||||||
|
|
||||||
(define (emit-initializer x port)
|
|
||||||
(display " " port)
|
|
||||||
(write (stob-header x) port)
|
|
||||||
(write-char #\, port)
|
|
||||||
(cond ((d-vector? x)
|
|
||||||
(emit-d-vector-initializer x port))
|
|
||||||
((vm-string? x)
|
|
||||||
(write-char #\" port)
|
|
||||||
(let ((len (vm-string-length x)))
|
|
||||||
(do ((i 0 (+ i 1)))
|
|
||||||
((= i len) (write-char #\" port))
|
|
||||||
(let ((c (vm-string-ref x i)))
|
|
||||||
(cond ((or (char=? c #\") (char=? c #\\))
|
|
||||||
(write-char #\\ port))
|
|
||||||
((char=? c #\newline)
|
|
||||||
(display "\\n\\" port)))
|
|
||||||
(write-char c port)))))
|
|
||||||
(else
|
|
||||||
(write-char #\{ port)
|
|
||||||
(let ((len (b-vector-length x)))
|
|
||||||
(do ((i 0 (+ i 1)))
|
|
||||||
((= i len) (write-char #\} port))
|
|
||||||
(write (b-vector-ref x i) port)
|
|
||||||
(write-char #\, port)))))
|
|
||||||
(write-char #\, port)
|
|
||||||
(if *comments?*
|
|
||||||
(begin (display " /* " port)
|
|
||||||
(writex x port)
|
|
||||||
(display " */" port)))
|
|
||||||
(newline port))
|
|
||||||
|
|
||||||
(define (emit-d-vector-initializer x port)
|
|
||||||
(write-char #\{ port)
|
|
||||||
(let ((len (d-vector-length x)))
|
|
||||||
(do ((i 0 (+ i 1)))
|
|
||||||
((= i len) (write-char #\} port))
|
|
||||||
(emit-descriptor (d-vector-ref x i) port)
|
|
||||||
(write-char #\, port))))
|
|
||||||
|
|
||||||
(define (emit-descriptor x port)
|
|
||||||
(if (stob? x)
|
|
||||||
(begin (if (immutable? x)
|
|
||||||
(display "D(p" port)
|
|
||||||
(display "D(i" port))
|
|
||||||
(display (chunk-number x) port)
|
|
||||||
(display ".x" port)
|
|
||||||
(writex x port)
|
|
||||||
(write-char #\) port))
|
|
||||||
(write x port)))
|
|
||||||
|
|
||||||
; hacked emit-descriptor returns chunk or #f
|
|
||||||
(define (descriptor-include x)
|
|
||||||
(if (stob? x)
|
|
||||||
(string-append
|
|
||||||
(if (immutable? x) "p" "i")
|
|
||||||
(number->string (chunk-number x)))
|
|
||||||
#f))
|
|
||||||
|
|
||||||
; Foo
|
|
||||||
|
|
||||||
(define (writex x port)
|
|
||||||
(write (quotient (- (- x (memory-begin)) 7) 4) port))
|
|
||||||
|
|
||||||
(define (chunk-number x)
|
|
||||||
(quotient (- (- x (memory-begin)) 7) *chunk-size*))
|
|
||||||
|
|
||||||
|
|
||||||
; Image traversal utility
|
|
||||||
|
|
||||||
(define (for-each-stored-object suffix chunk-start proc chunk-end)
|
|
||||||
(let ((limit (heap-pointer)))
|
|
||||||
(let chunk-loop ((addr (newspace-begin))
|
|
||||||
(i 0)
|
|
||||||
(chunk (+ (newspace-begin) *chunk-size*)))
|
|
||||||
(if (addr< addr limit)
|
|
||||||
(begin
|
|
||||||
(chunk-start i)
|
|
||||||
(let loop ((addr addr))
|
|
||||||
(if (and (addr< addr limit)
|
|
||||||
(addr< addr chunk))
|
|
||||||
(let ((d (fetch addr)))
|
|
||||||
(if (not (header? d))
|
|
||||||
(warn "heap is in an inconsistent state" d))
|
|
||||||
(proc (address->stob-descriptor (addr1+ addr)))
|
|
||||||
(loop (addr1+ (addr+ addr (header-a-units d)))))
|
|
||||||
(begin (chunk-end i)
|
|
||||||
(chunk-loop addr
|
|
||||||
(+ i 1)
|
|
||||||
(+ chunk *chunk-size*))))))))))
|
|
||||||
|
|
||||||
(define (mutable? x) (not (immutable? x)))
|
|
Loading…
Reference in New Issue