1 ;;;; variable-length encoding and other i/o tricks for the debugger
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
17 ;;;; reading variable length integers
19 ;;;; The debug info representation makes extensive use of integers
20 ;;;; encoded in a byte vector using a variable number of bytes:
21 ;;;; 0..253 => the integer
22 ;;;; 254 => read next two bytes for integer
23 ;;;; 255 => read next four bytes for integer
25 ;;; Given a byte vector Vec and an index variable Index, read a variable
26 ;;; length integer and advance index.
27 (defmacro read-var-integer (vec index)
28 (once-only ((val `(aref ,vec ,index)))
34 (logior (aref ,vec (+ ,index 1))
35 (ash (aref ,vec (+ ,index 2)) 8))
39 (logior (aref ,vec (+ ,index 1))
40 (ash (aref ,vec (+ ,index 2)) 8)
41 (ash (aref ,vec (+ ,index 3)) 16)
42 (ash (aref ,vec (+ ,index 4)) 24))
45 ;;; Takes an adjustable vector Vec with a fill pointer and pushes the
46 ;;; variable length representation of Int on the end.
47 (defun write-var-integer (int vec)
48 (declare (type (unsigned-byte 32) int))
50 (vector-push-extend int vec))
52 (let ((32-p (> int #xFFFF)))
53 (vector-push-extend (if 32-p 255 254) vec)
54 (vector-push-extend (ldb (byte 8 0) int) vec)
55 (vector-push-extend (ldb (byte 8 8) int) vec)
57 (vector-push-extend (ldb (byte 8 16) int) vec)
58 (vector-push-extend (ldb (byte 8 24) int) vec)))))
63 ;;;; A packed string is a variable length integer length followed by the
66 ;;; Read a packed string from Vec starting at Index, advancing Index.
67 (defmacro read-var-string (vec index)
68 (once-only ((len `(read-var-integer ,vec ,index)))
69 (once-only ((res `(make-string ,len)))
71 (%primitive byte-blt ,vec ,index ,res 0 ,len)
75 ;;; Write String into Vec (adjustable, fill-pointer) represented as the
76 ;;; length (in a var-length integer) followed by the codes of the characters.
77 (defun write-var-string (string vec)
78 (declare (simple-string string))
79 (let ((len (length string)))
80 (write-var-integer len vec)
82 (vector-push-extend (char-code (schar string i)) vec)))
85 ;;;; packed bit vectors
87 ;;; Read the specified number of Bytes out of Vec at Index and convert them
88 ;;; to a bit-vector. Index is incremented.
89 (defmacro read-packed-bit-vector (bytes vec index)
90 (once-only ((n-bytes bytes))
91 (once-only ((n-res `(make-array (* ,n-bytes 8) :element-type 'bit)))
93 (%primitive byte-blt ,vec ,index ,n-res 0 ,n-bytes)
94 (incf ,index ,n-bytes)