1 ;;; Guile Virtual Machine Assembly
3 ;; Copyright (C) 2001, 2009 Free Software Foundation, Inc.
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; This program is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;; GNU General Public License for more details.
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with this program; see the file COPYING. If not, write to
17 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 ;; Boston, MA 02111-1307, USA.
22 (define-module (language assembly)
23 #:use-module (system base pmatch)
24 #:use-module (system vm instruction)
25 #:use-module ((srfi srfi-1) #:select (fold))
28 assembly-pack assembly-unpack
29 object->assembly assembly->object))
31 ;; nargs, nrest, nlocs, nexts, len, metalen
32 (define *program-header-len* (+ 1 1 1 1 4 4))
34 ;; lengths are encoded in 3 bytes
37 (define (byte-length assembly)
39 (,label (guard (not (pair? label)))
41 ((load-unsigned-integer ,str)
42 (+ 1 *len-len* (string-length str)))
44 (+ 1 *len-len* (string-length str)))
46 (+ 1 *len-len* (string-length str)))
48 (+ 1 *len-len* (string-length str)))
50 (+ 1 *len-len* (string-length str)))
52 (+ 1 *len-len* (string-length str)))
54 (+ 1 *len-len* (string-length str)))
55 ((load-program ,nargs ,nrest ,nlocs ,nexts ,labels ,len ,meta . ,code)
56 (+ 1 *program-header-len* len (if meta (1- (byte-length meta)) 0)))
57 ((,inst . _) (guard (>= (instruction-length inst) 0))
58 (+ 1 (instruction-length inst)))
59 (else (error "unknown instruction" assembly))))
62 (define *program-alignment* 8)
64 (define (addr+ addr code)
65 (fold (lambda (x len) (+ (byte-length x) len))
69 (define (align-program prog addr)
70 `(,@(make-list (modulo (- *program-alignment*
71 (modulo (1+ addr) *program-alignment*))
72 ;; plus the one for the load-program inst itself
78 ;;; Code compress/decompression
81 (define *abbreviations*
82 '(((make-int8 0) . (make-int8:0))
83 ((make-int8 1) . (make-int8:1))))
86 (map (lambda (x) (cons (cdr x) (car x))) *abbreviations*))
88 (define (assembly-pack code)
89 (or (assoc-ref *abbreviations* code)
92 (define (assembly-unpack code)
93 (or (assoc-ref *expansions* code)
101 (define (object->assembly x)
102 (cond ((eq? x #t) `(make-true))
103 ((eq? x #f) `(make-false))
104 ((null? x) `(make-eol))
105 ((and (integer? x) (exact? x))
106 (cond ((and (<= -128 x) (< x 128))
107 `(make-int8 ,(modulo x 256)))
108 ((and (<= -32768 x) (< x 32768))
109 (let ((n (if (< x 0) (+ x 65536) x)))
110 `(make-int16 ,(quotient n 256) ,(modulo n 256))))
112 ((char? x) `(make-char8 ,(char->integer x)))
115 (define (assembly->object code)
118 ((make-false) #f) ;; FIXME: Same as the `else' case!
121 (if (< n 128) n (- n 256)))
122 ((make-int16 ,n1 ,n2)
123 (let ((n (+ (* n1 256) n2)))
124 (if (< n 32768) n (- n 65536))))
128 ((load-symbol ,s) (string->symbol s))
129 ((load-keyword ,s) (symbol->keyword (string->symbol s)))