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
	
	 bdc
						bdc