Разобранный байт-код
Люди не пишут байт-код; эту работу выполняет байт-компилятор. Но мы предоставляем дизассемблер для удовлетворения кошачьей любознательности. Дизассемблер преобразует байткодированный код в удобочитаемый вид.
Интерпретатор байт-кода реализован как простая стековая машина. Он помещает значения на свою собственную стек, затем извлекает их, чтобы использовать их в вычислениях, результаты которых снова помещаются в стек. Когда функция байт-кода возвращается, она извлекает значение из стека и возвращает его как значение функции.
Помимо стека, функции байт-кода могут использовать, связывать и устанавливать обычные переменные Lisp, передавая значения между переменными и стеком.
- Команда: disassemble объект &опционально буфер-или-имя
-
Эта команда отображает разобранный код для объекта. В интерактивном режиме или если буфер-или-имя равно
nilили опущено, вывод попадает в буфер с именем *Disassemble*. Если буфер-или-имя неnil, оно должно быть буфером или именем существующего буфера. Затем вывод попадает туда, в точку, и точка остается перед выводом.Аргумент объект может быть именем функции, лямбда-выражением (см. Лямбда-выражения) или объектом байт-кода (см. Объекты байт-кода). Если это лямбда-выражение,
disassembleкомпилирует его и дизассемблирует полученный скомпилированный код.
Вот два примера использования функции disassemble. Мы добавили поясняющие комментарии, чтобы помочь вам связать байт-код с исходным кодом Lisp; они не отображаются в выводе disassemble.
(defun factorial (integer)
"Compute factorial of an integer."
(if (= 1 integer) 1
(* integer (factorial (1- integer)))))
⇒ factorial
(factorial 4)
⇒ 24
(disassemble 'factorial)
-| byte-code for factorial:
doc: Compute factorial of an integer.
args: (integer)
0 varref integer ; Get the value of integer and
; push it onto the stack.
1 constant 1 ; Push 1 onto stack.
2 eqlsign ; Pop top two values off stack, compare ; them, and push result onto stack.
3 goto-if-nil 1 ; Pop and test top of stack;
; if nil, go to 1, else continue.
6 constant 1 ; Push 1 onto top of stack.
7 return ; Return the top element of the stack.
8:1 varref integer ; Push value ofintegeronto stack. 9 constant factorial ; Pushfactorialonto stack. 10 varref integer ; Push value ofintegeronto stack. 11 sub1 ; Popinteger, decrement value, ; push new value onto stack. 12 call 1 ; Call functionfactorialusing first ; (i.e., top) stack element as argument; ; push returned value onto stack.
13 mult ; Pop top two values off stack, multiply ; them, and push result onto stack. 14 return ; Return the top element of the stack.
Функция silly-loop несколько сложнее:
(defun silly-loop (n)
"Return time before and after N iterations of a loop."
(let ((t1 (current-time-string)))
(while (> (setq n (1- n))
0))
(list t1 (current-time-string))))
⇒ silly-loop
(disassemble 'silly-loop)
-| byte-code for silly-loop:
doc: Return time before and after N iterations of a loop.
args: (n)
0 constant current-time-string ; Push current-time-string
; onto top of stack.
1 call 0 ; Call current-time-string with no
; argument, push result onto stack.
2 varbind t1 ; Pop stack and bind t1 to popped value.
3:1 varref n ; Get value of n from the environment
; and push the value on the stack.
4 sub1 ; Subtract 1 from top of stack.
5 dup ; Duplicate top of stack; i.e., copy the top ; of the stack and push copy onto stack. 6 varset n ; Pop the top of the stack, ; and bindnto the value. ;; (In effect, the sequencedup varsetcopies the top of the stack ;; into the value ofnwithout popping it.)
7 constant 0 ; Push 0 onto stack. 8 gtr ; Pop top two values off stack, ; test if n is greater than 0 ; and push result onto stack.
9 goto-if-not-nil 1 ; Goto 1 if n > 0
; (this continues the while loop)
; else continue.
12 varref t1 ; Push value oft1onto stack. 13 constant current-time-string ; Pushcurrent-time-string; onto the top of the stack. 14 call 0 ; Callcurrent-time-stringagain.
15 unbind 1 ; Unbind t1 in local environment.
16 list2 ; Pop top two elements off stack, create a
; list of them, and push it onto stack.
17 return ; Return value of the top of stack.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Disassembly.html