-
Notifications
You must be signed in to change notification settings - Fork 11
/
instructions.texi
4816 lines (3891 loc) · 109 KB
/
instructions.texi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
@node Emacs Lisp Bytecode Instructions
@chapter Emacs Lisp Bytecode Instructions
Although we document bytecode instructions here, the implementation of
the bytecode interpreter and its instructions appear in
@file{src/bytecode.c}. If there is any question, that should be
consulted as the primary reference.
@menu
* Instruction-Description Format::
* Argument-Packing Instructions::
* Constants-Vector Retrieval Instructions::
* Exception-Handling Instructions::
* Control-Flow Instructions::
* Function-Call Instructions::
* Stack-Manipulation Instructions::
* Obsolete or Unused Instructions::
@end menu
@SECTIONA{Instruction-Description Format}
In this chapter we'll document instructions over the course of the
entire history of Emacs. Or at least we aim to.
For the opcode names, we will prefer canonicalized names from the
Emacs C source @code{bytecode.c} (under directory @code{src/}) when
those differ from the names in @code{bytecomp.el} (under directory
@code{lisp/emacs-lisp}). Most of the time they are the same under the
transformation described below.
We use names from @code{bytecode.c} because that is a larger set of
instruction names. Specifically, obsolete instructions names (both
those that can be interpreted even though they are no longer
generated, and some that are no longer interpreted) are defined in
that file, whereas that is not the case in @code{bytecomp.el}.
Names in @code{bytecode.c} must follow C conventions and must be
adjusted to harmonize with other C names used. But this aspect isn't
of use here, so we canonicalize those aspects away.
For example, in @code{bytecode.c} there is an opcode whose name is
@code{Bbuffer_substring}. We will drop the initial @code{B} and
replace all underscores (@verb{|_|}) with dashes
(@verb{|-|}). Therefore we use @code{buffer-substring}.
The corresponding name for that opcode in @code{bytecomp.el} is
@code{byte-buffer-substring}. For the most part, if you drop the
initial @code{byte-} prefix in the @code{bytecomp.el} name you will
often get the canonic name from @code{bytecode.c}.
However this isn't always true. The instruction that the Emacs Lisp
@code{save-current-buffer} function generates nowadays has opcode
value 114. In the C code, this value is listed as
@code{B_save_current_buffer_1}; @code{bytecomp.el} uses the name
@code{byte-save-current-buffer}. We report the instruction name for
opcode 114 as @code{save-current-buffer-1}.
To shorten and regularize instruction descriptions, each instruction
is described a standard format. We will also require a small
amount of jargon. This jargon are explained below.
@subsection Instruction Jargon
@itemize
@item @code{OPERAND}
The value of operand of the instruction. Many times this is done by
taking the value of the opcode and subtracting from it the value of
the first opcode in the series of opcodes it is part of. For example,
the @code{call} opcodes span opcode values 32 to 39. The
@code{OPERAND} value for opcode 32 then is @math{0 = 32-32}; for
opcode 33, the value is @math{1 = 33-32}.
@item @code{TOS}
The value of top of the evaluation stack. Many instructions either read or push onto this.
@item @code{S}
This is an array of evaluation stack items. @code{S[0]} is the top of
the stack, or @code{TOS}.
Note that indexing starts from the top of the stack and increases as
we move down the stack.
@item @code{top}
A pointer to the the top of the evaluation stack. In C this would be
@code{&TOS}. When we want the stack to increase in size, we add to
top. For example, to makes space to store a new single new value, we
can use @code{top++} and then assign to @code{TOS}.
Note that in changing @code{top}, the value accessed by @code{TOS} or
@code{S} values all change.
@item @math{\phi}
This is used in describing stack effects for branching instructions
where the stack effect is different on one branch versus the
other. This is a function of two arguments. The first argument gives
the stack effect on the non-nil branch and the second argument gives
the stack effect for the nil branch. So @math{\phi(0,-1)} which is
seen in @code{goto-if-not-nil-else-pop} means that if the jump is
taken, the stack effect is 0, otherwise the effect removes or pops an
evaluation-stack entry.
@item instruction-name subscripting (@code{[]})
In many instructions such as @code{constant}, @code{varref}, you will
find an index after the instruction name. What's going on is that
instruction name is one of a number of opcodes in a class encodes an
index into the instruction. We generally call this an
``Argument-encoding'' instruction. In the display of the opcode in
assembly listings and in the opcode table chapter where we list each
opcode, we will include that particular instruction variant in
subscripts.
For example consider @code{constant[0]} versus @code{constant[1]}.
The former has opcode 192 while the latter has opcode 193. In terms of
semantics, the former is the first or zeroth-index entry in a function's constant
vector while the latter is the second or 1-index entry.
@item eval stack types
Just as in Emacs Lisp, many functions expect their arguments to be of
a certain type, so it is true in Bytecode. Although the information
here mirrors what is described in the Emacs Lisp Reference Manual
(@pxref{Lisp Data Types, , Lisp Data Types, elisp, The GNU Emacs Lisp
Reference Manual}), for convenience we include that here as well.
@end itemize
@subsection Instruction Description Fields
The description of fields use for describing each instruction is as follows
@table @strong
@item Implements:
A description of what the instruction does.
@item Generated via:
These give some Emacs Lisp constructs that may generate the instruction. Of
course there may be many constructs and there may be limiting
situations within that construct. We'll only give one or a few of the
constructs, and we'll try to indicate a limiting condition where
possible.
@item Operand:
When an instruction has an operand, this describes the type of the
operand. Note that the size of the operand (or in some cases the
operand value) will determine the instruction size.
@item Instruction size:
The number of bytes in the instruction. This is 1 to 3 bytes.
@item Stack effect:
This describes how many stack entries are read and popped and how many
entries stack entries are pushed. Although this is logically a tuple,
we'll list this a tuple like @math{(-3, 2)} as a single scalar
@math{-3+2}. In this example, we read/remove three stack entries and
add two. The reason we give this as @math{-3+2} rather than the tuple
format is so that the overall effect (removing a stack entry) can be
seen by evaluating the expression.
@item Added in:
This is optional. When it is given this gives which version of Emacs
the opcode was added. It may also give when the opcode became obsolete
or was no longer implemented.
@item Example:
Some Emacs Lisp code to show how the instruction is used. For example
the for the @code{goto} instruction we give:
@verbatim
(defun goto-eg(n)
(while (n) 1300))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 192 constant[0] n
1 32 call[0]
2 133 goto-if-nil-else-pop [8]
8
0
5 130 goto [0]
0
0
8 135 return
Constants Vector: [n]
@end verbatim
From the above we see that the @code{goto} instruction at
program counter (PC) 5, has decimal opcode 130. The instruction is three bytes
long: a one-byte opcode followed by a two-byte operand.
The instruction name at PC 0 with opcode 192, @code{constant[0]},
looks like it is indexing, but it is a just name, where the brackets
and number are part of the name. We use this kind of name because it
is suggestive of how it works: it indexes the first element into the
constants vector and pushes that value onto the evaluation
stack. @code{constant[1]} with opcode 193 pushes the second element of
the constants vector onto the stack. We could have also used
instruction names like @code{constant0} and @code{constant1} for
opcodes 192 and 193 instead.
Unless otherwise stated, all code examples were compiled in Emacs 25
with optimization turned off.
@end table
@SECTION{Argument-Packing Instructions}
These instructions from opcode 1 to 47 encode an operand value from 0
to 7 encoded into the first byte. If the encoded value is 6, the actual
operand value is the byte following the opcode. If the encoded value
is 7, the actual operand value is the two-byte number following the
opcode, in Little-Endian byte order.
@menu
* stack-ref::
* varref::
* varset::
* varbind::
* call::
* unbind::
@end menu
@FirstSubSecInstruction{stack-ref, 1--7}
Reference a value from the evaluation stack.
@table @strong
@item Implements:
@code{top++; TOS <- S[OPERAND+1]}
@item Generated via:
@code{let}, @code{let*} and lambda arguments.
@item Operand:
A stack index
@item Instruction size:
1 byte for @code{stack-ref[0]} .. @code{stack-ref[4]}; 2 bytes for @code{stack-ref[5]}, 8-bit operand;
3 bytes for @code{stack-ref[6]}, 16-bit operand.
@item Stack effect:
@math{-0+1}.
@item Type Information:
@strong{after:} @code{TOS: Object}
@item Added in:
Emacs 24.1. @xref{Emacs 24}.
@item Example:
When lexical binding and optimization are in effect,
@verbatim
(defun stack-ref-eg()
(let ((a 5) (_b 6) (c 7))
(+ a c)))}
@end verbatim
generates:
@c ((lexical . t) (optimize . t))
@verbatim
PC Byte Instruction
0 192 constant[0] 5 ;; top++; TOS <- 5
1 193 constant[1] 6 ;; top++; TOS <- 6
2 194 constant[2] 7 ;; top++; TOS <- 7
3 2 stack-ref[2] ;; top++; TOS <- S[3] (5)
4 1 stack-ref[1] ;; top++; TOS <- S[2] (7)
5 92 plus
6 135 return
Constants Vector: [5 6 7]
@end verbatim
@end table
@strong{Warning}
Running an instruction with opcode 0 (logically this would be called
@code{stack-ref[0]}), will cause an immediate abort of Emacs in
versions after version 20 and before version 25! The abort of the
opcode was in place before this instruction was added.
Zero is typically an invalid in bytecode and in machine code, since
zero values are commonly found data, e.g. the end of C strings, or
data that has been initialized to value but represents data that
hasn't been written to yet. By having it be an invalid instruction, it
is more likely to catch situations where random sections of memory are
run such as by setting the PC incorrectly.
@SubSecInstruction{varref, 8--15}
Pushes the value of the symbol in the constants vector onto the
evaluation stack.
@kindex varref
@table @strong
@item Implements:
@code{top++; TOS <- (eval constants[OPERAND])}
@item Generated via:
dynamic variable access
@item Operand:
A constants vector index. The constants vector item should be a variable symbol.
@item Instruction size:
1 byte for @code{varref[0]} .. @code{varref[4]}; 2 bytes for @code{varref[5]},
8-bit operand; 3 bytes for @code{varref[6]}, 16-bit operand.
@item Stack effect:
@math{-0+1}.
@item Type Information:
@strong{after:} @code{TOS: Object}
@item Example:
When dynamic binding is in effect,
@verbatim
(defun varref-eg(n)
n)
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 8 varref[0] n
1 135 return
Constants Vector: [n]
@end verbatim
@end table
@SubSecInstruction{varset, 16--23}
Sets a variable listed in the constants vector to the TOS value
of the stack.
@kindex varset
@table @strong
@item Implements:
@code{constants[OPERAND] <- TOS; top--}
@item Operand:
A constants vector index. The constants vector item should be a variable symbol.
@item Instruction size:
1 byte for @code{varset[0]} .. @code{varset[4]}; 2 bytes for @code{varset[5]},
8-bit operand; 3 bytes for @code{varset[6]}, 16-bit operand.
@item Stack effect:
@math{-1+0}.
@item Type Information:
@strong{before:} @code{TOS: Object}
@item Example:
When dynamic binding is in effect,
@verbatim
(defun varset-eg(n)
(setq n 5))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 193 constant[1] 5
1 137 dup
2 16 varset[0] n ;; sets variable n
3 135 return
Constants Vector: [n 5]
@end verbatim
@end table
@SubSecInstruction{varbind, 24--31}
Binds a variable to a symbol in the constants vector, and adds the
symbol to a special-bindings stack.
@table @strong
@item Implements:
@code{*constants[OPERAND]<-TOS; top--}
@item Instruction size:
1 byte for @code{varbind[0]} .. @code{varbind[4]}; 2 bytes for @code{varbind[5]},
8-bit operand; 3 bytes for @code{varbind[6]}, 16-bit operand.
@item Stack effect:
@math{-1+0}.
@item Type Information:
@strong{before:} @code{TOS: Object}
@item Example:
When dynamic binding is in effect,
@verbatim
(defun varbind-eg()
(let ((c 1))
(1+ c)))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 193 constant[1] 1
1 137 dup
2 24 varbind[0] c ;; creates variable c
3 84 add1
4 41 unbind[1] ;; removes variable c
5 135 return
Constants Vector: [c 1]
@end verbatim
@end table
@SubSecInstruction{call, 32--39}
Calls a function. The instruction argument specifies the number of
arguments to pass to the function from the stack, excluding the
function itself.
@table @strong
@item Implements:
@verbatim
arg[0..OPERAND-1] = S[OPERAND-1..0]
fn <- S[OPERAND];
top -= OPERAND;
TOS <- fn(*arg) # replace fn by the fn's return value
@end verbatim
Before the call, the top of the stack has the final call parameter, if
there is one. If there are no parameters, the top of the stack has the
function to be called. The function to be called is always the least
recent evaluation stack entry followed the function parameters
in the order they were given.
For example, for @code{gcd(3, 5)} the operator is @code{call[2]} and
the value of @code{OPERAND} is 2. The evaluation stack before the
function call for this example would be:
@verbatim
+------------+
| S[0] : 5 |
+------------+
| S[1] : 3 |
+------------+
| S[2] : gcd |
+------------+
@end verbatim
After the call completes, the evaluation stack will be:
@verbatim
+-------------------------+
| S[0] : gcd-return-value |
+-------------------------+
@end verbatim
@item Instruction size:
1 byte for @code{call[0]} .. @code{call[5]}; 2 bytes for @code{call[6]},
8-bit operand; 3 bytes for @code{call[7]}, 16-bit operand.
@item Stack effect:
@math{-(@code{OPERAND}+1)+1}.
@item Example:
@verbatim
(defun call-eg()
(exchange-point-and-mark)
(next-line 2))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 192 constant[0] exchange-point-and-mark
1 32 call[0]
2 136 discard
3 193 constant[1] next-line
4 194 constant[2] 2
5 33 call[1]
6 135 return
Constants Vector: [exchange-point-and-mark next-line 2]
@end verbatim
@end table
@SubSecInstruction{unbind, 40--47}
@kindex unbind
Remove the binding of a variable to symbol and from the special
stack. This is done when the variable is no longer needed.
@table @strong
@item Implements:
undo's a @code{let}, @code{unwind-protect}s, and @code{save-excursion}s
@item Generated via:
@code{let} in dynamic binding. Balancing the end of @code{save-excursion}.
@item Instruction size:
1 byte for @code{unbind[0]} .. @code{unbind[4]}; 2 bytes for @code{unbind[5]},
8-bit operand; 3 bytes for @code{unbind[6]}, 16-bit operand.
@item Stack effect:
@math{-0+0}.
@item Example:
When dynamic binding is in effect,
@verbatim
(defun varbind-eg()
(let ((c 1))
(1+ c)))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 193 constant[1] 1
1 137 dup
2 24 varbind[0] c ;; creates variable c
3 84 add1
4 41 unbind[1] ;; removes variable c
5 135 return
Constants Vector: [c 1]
@end verbatim
@end table
@SECTION{Constants-Vector Retrieval Instructions}
The instructions from opcode 192 to 255 push a value from the
Constants Vector. @xref{Constants Vector}. Opcode 192 pushes the first
entry, opcode 193, the second and so on. If there are more than 64
constants, opcode @code{constant2} (opcode 129) is used instead.
@menu
* constant::
* constant2::
@end menu
@FirstSubSecInstruction{constant, 192--255}
@kindex constant
Pushes a value from the constants vector on the evaluation stack.
There are special instructions to push any one of the first
64 entries in the constants stack.
@table @strong
@item Implements:
@code{top++; TOS <- constants[OPERAND]}
@item Instruction size:
1 byte
@item Stack effect:
@math{-0+1}.
@item Type Information:
@strong{after:} @code{TOS: Object}
@item Example:
@verbatim
(defun n3(n)
(+ n 10 11 12))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 193 constant[1] +
1 8 varref[0] n
2 194 constant[2] 10
3 195 constant[3] 11
4 196 constant[4] 12
5 36 call[4]
6 135 return
Constants Vector: [n + 10 11 12]
@end verbatim
@end table
@SubSecInstruction{constant2, 129}
Pushes a value from the constants vector on the evaluation stack.
Although there are special instructions to push any one of the first
64 entries in the constants stack, this instruction is needed to push
a value beyond one the first 64 entries.
@table @strong
@item Implements:
@code{top++; TOS <- constants[OPERAND]}
@item Operand:
a 16-bit index into the constants vector.
@item Instruction size:
3 bytes
@item Stack effect:
@math{-0+1}.
@item Example:
@c @code{(defun n64 (n) (+ n 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64))} generates
@c ((optimize . nil))
@verbatim
(defun n64(n)
(+ n 0 1 2 3 .. 64))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 193 constant[1] +
1 8 varref[0] n
2 194 constant[2] 0
3 195 constant[3] 1
4 196 constant[4] 2
[...]
63 255 constant[63] 61
64 129 constant2 [64] 62
64
0
67 129 constant2 [65] 63
65
0
70 129 constant2 [66] 64
66
0
73 38 call [66]
66
75 135 return
Constants Vector: [n + 0 1 2 .. 61 62 63 64]
@end verbatim
@end table
@SECTION{Exception-Handling Instructions}
@menu
* pophandler::
* pushconditioncase::
* pushcatch::
@end menu
@FirstSubSecInstruction{pophandler, 48}
@table @strong
@item Implements:
Removes last condition pushed by @code{pushconditioncase}
@item Generated via:
@code{condition-case}
@item Instruction size:
1 byte
@item Stack effect:
@math{-0+0}.
@item Added in:
Emacs 24.4. @xref{Emacs 24}.
@item Example:
@verbatim
(defun pushconditioncase-eg()
(condition-case nil
5
(one-error 6)
(another-error 7)))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 192 constant[0] (another-error)
1 49 pushconditioncase [16]
16
0
4 193 constant[1] (one-error)
5 49 pushconditioncase [12]
12
0
8 194 constant[2] 5
9 48 pophandler
10 48 pophandler
11 135 return
12 48 pophandler
13 136 discard
14 195 constant[3] 6
15 135 return
16 136 discard
17 196 constant[4] 7
18 135 return
Constants Vector: [(another-error) (one-error) 5 6 7]
@end verbatim
@end table
@SubSecInstruction{pushconditioncase, 49}
@table @strong
@item Implements:
Pops the TOS which is some sort of condition to test on and
registers that. If any of the instructions errors with that condition,
a jump to the operand occurs.
@item Operand:
16-bit PC address
@item Instruction size:
3 bytes
@item Stack effect:
@math{-1+0}.
@item Added in:
Emacs 24.4. @xref{Emacs 24}.
@item Example:
@verbatim
(defun pushconditioncase-eg()
(condition-case nil
5
(one-error 6)
(another-error 7)))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 192 constant[0] (another-error)
1 49 pushconditioncase [16]
16
0
4 193 constant[1] (one-error)
5 49 pushconditioncase [12]
12
0
8 194 constant[2] 5
9 48 pophandler
10 48 pophandler
11 135 return
12 48 pophandler
13 136 discard
14 195 constant[3] 6
15 135 return
16 136 discard
17 196 constant[4] 7
18 135 return
Constants Vector: [(another-error) (one-error) 5 6 7]
@end verbatim
@end table
@SubSecInstruction{pushcatch, 50}
?
@SECTION{Control-Flow Instructions}
@menu
* goto::
* goto-if-nil::
* goto-if-not-nil::
* goto-if-nil-else-pop::
* goto-if-not-nil-else-pop::
* return::
* switch::
@end menu
@FirstSubSecInstruction{goto, 130}
@table @strong
@item Implements:
Jump to label given in the 16-bit operand
@item Generated via:
@code{while} and various control-flow constructs
@item Operand:
16-bit PC address
@item Instruction size:
3 bytes
@item Stack effect:
@math{-0+0}
@item Example:
@code{(defun goto-eg(n) (while (n) 1300))} generates:
@verbatim
PC Byte Instruction
0 192 constant[0] n
1 32 call[0]
2 133 goto-if-nil-else-pop [8]
8
0
5 130 goto [0]
0
0
8 135 return
Constants Vector: [n]
@end verbatim
@end table
@SubSecInstruction{goto-if-nil, 131}
@table @strong
@item Implements:
Jump to label given in the 16-bit operand if TOS is nil. In contrast to
@code{goto-if-nil-else-pop}, the test expression, TOS, is always popped.
@item Generated via:
@code{if} with ``else'' clause and various control-flow constructs
@item Operand:
16-bit PC address
@item Instruction size:
3 bytes
@item Stack effect:
@math{-1+0}
@item Example:
@code{(defun goto-if-nil-eg(n) (if (n) 1310 1311))} generates:
@c ((optimize . nil))
@verbatim
PC Byte Instruction
0 192 constant[0] n
1 32 call[0]
2 131 goto-if-nil [9]
9
0
5 193 constant[1] 1310
6 130 goto [10]
10
0
9 194 constant[2] 1311
10 135 return
Constants Vector: [n 1310 1311]
@end verbatim
@end table
@SubSecInstruction{goto-if-not-nil, 132}
@table @strong
@item Implements:
Jump to label given in the 16-bit operand if TOS is not nil. In
contrast to @code{goto-if-not-nil-else-pop}, the test expression, TOS, is
always popped.
@item Generated via:
@code{or} inside an @code{if} with optimization and various
control-flow constructs
@item Operand:
16-bit PC address
@item Instruction size:
3 bytes
@item Stack effect:
@math{-1+0}
@item Example:
With bytecode optimization, @code{(defun goto-if-not-nil-eg(n) (if (or (n) (n)) 1320))} generates:
@verbatim
PC Byte Instruction
0 192 constant[0] n
1 32 call[0]
2 132 goto-if-not-nil [10]
10
0
5 192 constant[0] n
6 32 call[0]
7 133 goto-if-nil-else-pop [11]
11
0
10 193 constant[1] 1320
11 135 return
Constants Vector: [n 1320]
@end verbatim
Note the change in opcode when bytecode optimization is not performed.
@end table
@SubSecInstruction{goto-if-nil-else-pop, 133}
@table @strong
@item Implements:
Jump to label given in the 16-bit operand if TOS is nil; otherwise pop
the TOS, the tested condition. This allows the test expression, nil,
to be used again on the branch as the TOS.
@item Generated via:
@code{cond}, @code{if} and various control-flow constructs
@item Operand:
16-bit PC address
@item Instruction size:
3 bytes
@item Stack effect:
@math{\phi(0,-1)+0}
@item Example:
@code{(defun goto-if-nil-else-pop-eg(n) (cond ((n) 1330)))} generates:
@verbatim
PC Byte Instruction
0 192 constant[0] n
1 32 call[0]
2 133 goto-if-nil-else-pop [6]
6
0
5 193 constant[1] 1330
6 135 return
Constants Vector: [n 1330]
@end verbatim
@end table
@SubSecInstruction{goto-if-not-nil-else-pop, 134}
@table @strong
@item Implements:
Jump to label given in the 16-bit operand if TOS is not nil; otherwise
pop TOS, the tested condition. This allows the tested expression on TOS to be used
again when the jump is taken.
@item Generated via:
@code{cond}, @code{if} and various control-flow constructs
@item Operand:
16-bit PC address
@item Instruction size:
3 bytes
@item Stack effect:
@math{\phi(0,-1)+0}
@item Example:
@c ((optimize . nil))
@verbatim
(defun goto-if-not-nil-else-pop-eg(n)
(if (or (n) (n))
1340))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 192 constant[0] n
1 32 call[0]
2 134 goto-if-not-nil-else-pop [7]
7
0
5 192 constant[0] n
6 32 call[0]
7 133 goto-if-nil-else-pop [11]
11
0
10 193 constant[1] 1340
11 135 return
Constants Vector: [n 1340]
@end verbatim
Note the change in opcode when bytecode optimization is performed.
@end table
@SubSecInstruction{return, 135}
@table @strong
@item Implements:
Return from function. This is the last instruction in a function's
bytecode sequence. The top value on the evaluation stack is the return value.
@item Generated via:
@code{lambda}
@item Instruction size:
1 byte
@item Stack effect:
@math{-1+0}
@item Example:
@code{(defun return-eg(n) 1350)} generates:
@verbatim
PC Byte Instruction
0 192 constant[0] 1350
1 135 return
Constants Vector: [1350]
@end verbatim
@end table
@SubSecInstruction{switch, 183}
Jumps to entry in a jump table.
@table @strong
@item Implements:
switch-like jump table. Top of stack is a variable reference. Below that
is a hash table mapping compared values to instruction addresses.
@code{v, ht <- TOS, S[1]; top -=2; pc = ht.lookup(v)}
Note: for efficiency, the bytecode interpreter tends to use actually
addresses rather than offsets off of bytecode start address. This is
seen here in the values stored in the lookup table.
@item Generated via:
@code{cond} with several clauses that use the same test function and variable.
@item Instruction size:
1 byte
@item Stack effect:
@math{-2+0}
@item Added in:
Emacs 26.1
@item Example:
@verbatim
(defun switch-eg(n)
(cond ((equal n 1) 1)
((equal n 2) 2)
((equal n 3) 3)))
@end verbatim
generates:
@verbatim
PC Byte Instruction
0 8 varref[0] n
1 193 constant[1] #s(hash-table size 3 test equal rehash-size 1.5 rehash-threshold 0.8125 purecopy t data (1 6 2 8 3 10))
2 183 switch
3 130 goto [12]
12
0
6 194 constant[2] 1
7 135 return
8 195 constant[3] 2
9 135 return
10 196 constant[4] 3
11 135 return
12 197 constant[5] nil
13 135 return
Constants Vector: [n #s(hash-table size 2 test equal rehash-size 1.5 rehash-threshold 0.8125 purecopy t data (1 6 2 8)) 1 3 nil]
@end verbatim
@end table
@SECTION{Function-Call Instructions}
These instructions use up one byte, and are followed by the next
instruction directly. They are equivalent to calling an Emacs Lisp
function with a fixed number of arguments: the arguments are popped
from the stack, and a single return value is pushed back onto the
stack.
@menu
* Lisp Function Instructions::
* List Function Instructions::
* Arithmetic Function Instructions::
* String Function Instructions::
* Emacs Buffer Instructions::
* Emacs Position Instructions::
* Emacs Text Instructions::
* Emacs Misc Function Instructions::
@end menu
@FirstSubsection{Lisp Function Instructions}
These instructions correspond to general functions which are not
specific to Emacs; common cases are usually inlined for speed by the
bytecode interpreter.
@menu