You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

158 lines
5.8 KiB
Scheme

;;; fasl-helpers.ss
;;; Copyright 1984-2017 Cisco Systems, Inc.
;;;
;;; Licensed under the Apache License, Version 2.0 (the "License");
;;; you may not use this file except in compliance with the License.
;;; You may obtain a copy of the License at
;;;
;;; http://www.apache.org/licenses/LICENSE-2.0
;;;
;;; Unless required by applicable law or agreed to in writing, software
;;; distributed under the License is distributed on an "AS IS" BASIS,
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;;; See the License for the specific language governing permissions and
;;; limitations under the License.
(module (put8 put16 put32 put64 put-iptr put-uptr)
(define (bit-mask k) (- (ash 1 k) 1))
(define put8
(lambda (p n)
(put-u8 p (fxlogand n (bit-mask 8)))))
(define put16-le
(cond
[(>= (most-positive-fixnum) (bit-mask 16))
(lambda (p n)
(put-u8 p (fxlogand n (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 8) (bit-mask 8))))]
[else ($oops 'put16-le "unsupported fixnum size")]))
(define put16-be
(cond
[(>= (most-positive-fixnum) (bit-mask 16))
(lambda (p n)
(put-u8 p (fxlogand (fxsrl n 8) (bit-mask 8)))
(put-u8 p (fxlogand n (bit-mask 8))))]
[else ($oops 'put16-be "unsupported fixnum size")]))
(define put16
(lambda (p n)
(constant-case native-endianness
[(little) (put16-le p n)]
[(big) (put16-be p n)])))
(define put32-le
(cond
[(>= (most-positive-fixnum) (bit-mask 32))
(lambda (p n)
(put-u8 p (fxlogand n (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 8) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 16) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 24) (bit-mask 8))))]
[(>= (most-positive-fixnum) (bit-mask 24))
(lambda (p n)
(cond
[(fixnum? n)
(put-u8 p (fxlogand n (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 8) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 16) (bit-mask 8)))
(put-u8 p (fxlogand (fxsra n 24) (bit-mask 8)))]
[else
(let ([n (logand n (bit-mask 16))])
(put-u8 p (fxlogand n (bit-mask 8)))
(put-u8 p (fxsrl n 8)))
(let ([n (ash n -16)])
(put-u8 p (fxlogand n (bit-mask 8)))
(put-u8 p (fxlogand (fxsra n 8) (bit-mask 8))))]))]
[else ($oops 'put32-le "unsupported fixnum size")]))
(define put32-be
(cond
[(>= (most-positive-fixnum) (bit-mask 32))
(lambda (p n)
(put-u8 p (fxlogand (fxsrl n 24) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 16) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 8) (bit-mask 8)))
(put-u8 p (fxlogand n (bit-mask 8))))]
[(>= (most-positive-fixnum) (bit-mask 24))
(lambda (p n)
(cond
[(fixnum? n)
(put-u8 p (fxlogand (fxsra n 24) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 16) (bit-mask 8)))
(put-u8 p (fxlogand (fxsrl n 8) (bit-mask 8)))
(put-u8 p (fxlogand n (bit-mask 8)))]
[else
(let ([n (ash n -16)])
(put-u8 p (fxlogand (fxsra n 8) (bit-mask 8)))
(put-u8 p (fxlogand n (bit-mask 8))))
(let ([n (logand n (bit-mask 16))])
(put-u8 p (fxsrl n 8))
(put-u8 p (fxlogand n (bit-mask 8))))]))]
[else ($oops 'put32-be "unsupported fixnum size")]))
(define put32
(lambda (p n)
(constant-case native-endianness
[(little) (put32-le p n)]
[(big) (put32-be p n)])))
(define put64-le
(lambda (p n)
(cond
[(and (>= (most-positive-fixnum) (bit-mask 32)) (fixnum? n))
(put32-le p (fxlogand n (bit-mask 32)))
(put32-le p (ash n -32))]
[else
(put32-le p (logand n (bit-mask 32)))
(put32-le p (ash n -32))])))
(define put64-be
(lambda (p n)
(cond
[(and (>= (most-positive-fixnum) (bit-mask 32)) (fixnum? n))
(put32-be p (ash n -32))
(put32-be p (fxlogand n (bit-mask 32)))]
[else
(put32-be p (ash n -32))
(put32-be p (logand n (bit-mask 32)))])))
(define put64
(lambda (p n)
(constant-case native-endianness
[(little) (put64-le p n)]
[(big) (put64-be p n)])))
(define put-iptr
(lambda (p n0)
(let f ([n (if (< n0 0) (- n0) n0)] [cbit 0])
(if (and (fixnum? n) (fx<= n 63))
(put8 p (fxlogor (if (< n0 0) #x80 0) (fxsll n 1) cbit))
(begin
(f (ash n -7) 1)
(put-u8 p (fxlogor (fxsll (logand n #x7f) 1) cbit)))))))
(define put-uptr
(lambda (p n)
(unless (>= n 0)
($oops 'compiler-internal "put-uptr received negative input ~s" n))
(let f ([n n] [cbit 0])
(if (and (fixnum? n) (fx<= n 127))
(put-u8 p (fxlogor (fxsll n 1) cbit))
(begin
(f (ash n -7) 1)
(put-u8 p (fxlogor (fxsll (logand n #x7f) 1) cbit)))))))
)
(define emit-header
(case-lambda
[(p version mtype) (emit-header p version mtype '())]
[(p version mtype bootfiles)
(define (put-str p s)
(let ([n (string-length s)])
(do ([i 0 (fx+ i 1)])
((fx= i n))
(let* ([c (string-ref s i)] [k (char->integer c)])
(unless (fx<= k 255)
($oops #f "cannot handle bootfile name character ~s whose integer code exceeds 255" c))
(put-u8 p k)))))
(put-bytevector p (constant fasl-header))
(put-uptr p version)
(put-uptr p mtype)
(put-u8 p (char->integer #\()) ; )
(let f ([bootfiles bootfiles] [sep? #f])
(unless (null? bootfiles)
(when sep? (put-u8 p (char->integer #\space)))
(put-str p (car bootfiles))
(f (cdr bootfiles) #t))) ; (
(put-u8 p (char->integer #\)))]))