Commit | Line | Data |
---|---|---|
8680d53b AW |
1 | @c -*-texinfo-*- |
2 | @c This is part of the GNU Guile Reference Manual. | |
747bd534 | 3 | @c Copyright (C) 2008,2009,2010,2011,2013 |
8680d53b AW |
4 | @c Free Software Foundation, Inc. |
5 | @c See the file guile.texi for copying conditions. | |
6 | ||
7 | @node A Virtual Machine for Guile | |
8 | @section A Virtual Machine for Guile | |
9 | ||
f11871d6 AW |
10 | Guile has both an interpreter and a compiler. To a user, the difference |
11 | is transparent---interpreted and compiled procedures can call each other | |
12 | as they please. | |
090d51ed AW |
13 | |
14 | The difference is that the compiler creates and interprets bytecode | |
15 | for a custom virtual machine, instead of interpreting the | |
98850fd7 AW |
16 | S-expressions directly. Loading and running compiled code is faster |
17 | than loading and running source code. | |
090d51ed AW |
18 | |
19 | The virtual machine that does the bytecode interpretation is a part of | |
20 | Guile itself. This section describes the nature of Guile's virtual | |
21 | machine. | |
22 | ||
8680d53b AW |
23 | @menu |
24 | * Why a VM?:: | |
25 | * VM Concepts:: | |
26 | * Stack Layout:: | |
27 | * Variables and the VM:: | |
00ce5125 | 28 | * VM Programs:: |
1f6f591d | 29 | * Object File Format:: |
8680d53b AW |
30 | * Instruction Set:: |
31 | @end menu | |
32 | ||
33 | @node Why a VM? | |
34 | @subsection Why a VM? | |
35 | ||
86872cc3 | 36 | @cindex interpreter |
f11871d6 AW |
37 | For a long time, Guile only had an interpreter. Guile's interpreter |
38 | operated directly on the S-expression representation of Scheme source | |
39 | code. | |
090d51ed | 40 | |
f11871d6 | 41 | But while the interpreter was highly optimized and hand-tuned, it still |
9e9745b3 | 42 | performed many needless computations during the course of evaluating an |
e3ba263d | 43 | expression. For example, application of a function to arguments |
f11871d6 AW |
44 | needlessly consed up the arguments in a list. Evaluation of an |
45 | expression always had to figure out what the car of the expression is -- | |
46 | a procedure, a memoized form, or something else. All values have to be | |
47 | allocated on the heap. Et cetera. | |
090d51ed | 48 | |
f11871d6 | 49 | The solution to this problem was to compile the higher-level language, |
090d51ed | 50 | Scheme, into a lower-level language for which all of the checks and |
86872cc3 | 51 | dispatching have already been done---the code is instead stripped to |
090d51ed AW |
52 | the bare minimum needed to ``do the job''. |
53 | ||
54 | The question becomes then, what low-level language to choose? There | |
55 | are many options. We could compile to native code directly, but that | |
56 | poses portability problems for Guile, as it is a highly cross-platform | |
57 | project. | |
58 | ||
59 | So we want the performance gains that compilation provides, but we | |
60 | also want to maintain the portability benefits of a single code path. | |
61 | The obvious solution is to compile to a virtual machine that is | |
62 | present on all Guile installations. | |
63 | ||
64 | The easiest (and most fun) way to depend on a virtual machine is to | |
65 | implement the virtual machine within Guile itself. This way the | |
66 | virtual machine provides what Scheme needs (tail calls, multiple | |
86872cc3 AW |
67 | values, @code{call/cc}) and can provide optimized inline instructions |
68 | for Guile (@code{cons}, @code{struct-ref}, etc.). | |
090d51ed AW |
69 | |
70 | So this is what Guile does. The rest of this section describes that VM | |
71 | that Guile implements, and the compiled procedures that run on it. | |
72 | ||
f11871d6 AW |
73 | Before moving on, though, we should note that though we spoke of the |
74 | interpreter in the past tense, Guile still has an interpreter. The | |
75 | difference is that before, it was Guile's main evaluator, and so was | |
76 | implemented in highly optimized C; now, it is actually implemented in | |
77 | Scheme, and compiled down to VM bytecode, just like any other program. | |
78 | (There is still a C interpreter around, used to bootstrap the compiler, | |
79 | but it is not normally used at runtime.) | |
80 | ||
81 | The upside of implementing the interpreter in Scheme is that we preserve | |
82 | tail calls and multiple-value handling between interpreted and compiled | |
23e2e780 | 83 | code. The downside is that the interpreter in Guile 2.2 is still slower |
0c81a0c1 | 84 | than the interpreter in 1.8. We hope the that the compiler's speed makes |
23e2e780 AW |
85 | up for the loss. In any case, once we have native compilation for |
86 | Scheme code, we expect the new self-hosted interpreter to beat the old | |
87 | hand-tuned C implementation. | |
f11871d6 AW |
88 | |
89 | Also note that this decision to implement a bytecode compiler does not | |
090d51ed AW |
90 | preclude native compilation. We can compile from bytecode to native |
91 | code at runtime, or even do ahead of time compilation. More | |
86872cc3 | 92 | possibilities are discussed in @ref{Extending the Compiler}. |
8680d53b AW |
93 | |
94 | @node VM Concepts | |
95 | @subsection VM Concepts | |
96 | ||
23e2e780 AW |
97 | Compiled code is run by a virtual machine (VM). Each thread has its own |
98 | VM. The virtual machine executes the sequence of instructions in a | |
99 | procedure. | |
8680d53b | 100 | |
23e2e780 AW |
101 | Each VM instruction starts by indicating which operation it is, and then |
102 | follows by encoding its source and destination operands. Each procedure | |
103 | declares that it has some number of local variables, including the | |
104 | function arguments. These local variables form the available operands | |
105 | of the procedure, and are accessed by index. | |
8680d53b | 106 | |
23e2e780 AW |
107 | The local variables for a procedure are stored on a stack. Calling a |
108 | procedure typically enlarges the stack, and returning from a procedure | |
109 | shrinks it. Stack memory is exclusive to the virtual machine that owns | |
110 | it. | |
8680d53b | 111 | |
23e2e780 AW |
112 | In addition to their stacks, virtual machines also have access to the |
113 | global memory (modules, global bindings, etc) that is shared among other | |
114 | parts of Guile, including other VMs. | |
8680d53b AW |
115 | |
116 | The registers that a VM has are as follows: | |
117 | ||
118 | @itemize | |
119 | @item ip - Instruction pointer | |
120 | @item sp - Stack pointer | |
121 | @item fp - Frame pointer | |
122 | @end itemize | |
123 | ||
23e2e780 AW |
124 | In other architectures, the instruction pointer is sometimes called the |
125 | ``program counter'' (pc). This set of registers is pretty typical for | |
126 | virtual machines; their exact meanings in the context of Guile's VM are | |
127 | described in the next section. | |
81fd3152 | 128 | |
8680d53b AW |
129 | @node Stack Layout |
130 | @subsection Stack Layout | |
131 | ||
23e2e780 AW |
132 | The stack of Guile's virtual machine is composed of @dfn{frames}. Each |
133 | frame corresponds to the application of one compiled procedure, and | |
134 | contains storage space for arguments, local variables, and some | |
135 | bookkeeping information (such as what to do after the frame is | |
136 | finished). | |
8680d53b AW |
137 | |
138 | While the compiler is free to do whatever it wants to, as long as the | |
139 | semantics of a computation are preserved, in practice every time you | |
140 | call a function, a new frame is created. (The notable exception of | |
141 | course is the tail call case, @pxref{Tail Calls}.) | |
142 | ||
23e2e780 | 143 | The structure of the top stack frame is as follows: |
8680d53b AW |
144 | |
145 | @example | |
23e2e780 AW |
146 | /------------------\ <- top of stack |
147 | | Local N-1 | <- sp | |
8274228f | 148 | | ... | |
23e2e780 AW |
149 | | Local 1 | |
150 | | Local 0 | <- fp = SCM_FRAME_LOCALS_ADDRESS (fp) | |
8274228f | 151 | +==================+ |
8274228f | 152 | | Return address | |
23e2e780 | 153 | | Dynamic link | <- fp - 2 = SCM_FRAME_LOWER_ADDRESS (fp) |
8274228f | 154 | +==================+ |
23e2e780 | 155 | | | <- fp - 3 = SCM_FRAME_PREVIOUS_SP (fp) |
8680d53b AW |
156 | @end example |
157 | ||
23e2e780 AW |
158 | In the above drawing, the stack grows upward. Usually the procedure |
159 | being applied is in local 0, followed by the arguments from local 1. | |
160 | After that are enough slots to store the various lexically-bound and | |
161 | temporary values that are needed in the function's application. | |
162 | ||
163 | The @dfn{return address} is the @code{ip} that was in effect before this | |
164 | program was applied. When we return from this activation frame, we will | |
165 | jump back to this @code{ip}. Likewise, the @dfn{dynamic link} is the | |
166 | @code{fp} in effect before this program was applied. | |
167 | ||
168 | To prepare for a non-tail application, Guile's VM will emit code that | |
169 | shuffles the function to apply and its arguments into appropriate stack | |
170 | slots, with two free slots below them. The call then initializes those | |
171 | free slots with the current @code{ip} and @code{fp}, and updates | |
172 | @code{ip} to point to the function entry, and @code{fp} to point to the | |
173 | new call frame. | |
174 | ||
175 | In this way, the dynamic link links the current frame to the previous | |
176 | frame. Computing a stack trace involves traversing these frames. | |
8680d53b AW |
177 | |
178 | @node Variables and the VM | |
179 | @subsection Variables and the VM | |
180 | ||
81fd3152 | 181 | Consider the following Scheme code as an example: |
8680d53b AW |
182 | |
183 | @example | |
184 | (define (foo a) | |
185 | (lambda (b) (list foo a b))) | |
186 | @end example | |
187 | ||
23e2e780 AW |
188 | Within the lambda expression, @code{foo} is a top-level variable, |
189 | @code{a} is a lexically captured variable, and @code{b} is a local | |
190 | variable. | |
98850fd7 | 191 | |
23e2e780 AW |
192 | Another way to refer to @code{a} and @code{b} is to say that @code{a} is |
193 | a ``free'' variable, since it is not defined within the lambda, and | |
98850fd7 | 194 | @code{b} is a ``bound'' variable. These are the terms used in the |
23e2e780 AW |
195 | @dfn{lambda calculus}, a mathematical notation for describing functions. |
196 | The lambda calculus is useful because it is a language in which to | |
197 | reason precisely about functions and variables. It is especially good | |
198 | at describing scope relations, and it is for that reason that we mention | |
199 | it here. | |
98850fd7 AW |
200 | |
201 | Guile allocates all variables on the stack. When a lexically enclosed | |
f11871d6 AW |
202 | procedure with free variables---a @dfn{closure}---is created, it copies |
203 | those variables into its free variable vector. References to free | |
98850fd7 AW |
204 | variables are then redirected through the free variable vector. |
205 | ||
206 | If a variable is ever @code{set!}, however, it will need to be | |
207 | heap-allocated instead of stack-allocated, so that different closures | |
208 | that capture the same variable can see the same value. Also, this | |
209 | allows continuations to capture a reference to the variable, instead | |
210 | of to its value at one point in time. For these reasons, @code{set!} | |
211 | variables are allocated in ``boxes''---actually, in variable cells. | |
212 | @xref{Variables}, for more information. References to @code{set!} | |
213 | variables are indirected through the boxes. | |
214 | ||
215 | Thus perhaps counterintuitively, what would seem ``closer to the | |
216 | metal'', viz @code{set!}, actually forces an extra memory allocation | |
217 | and indirection. | |
218 | ||
219 | Going back to our example, @code{b} may be allocated on the stack, as | |
220 | it is never mutated. | |
221 | ||
222 | @code{a} may also be allocated on the stack, as it too is never | |
223 | mutated. Within the enclosed lambda, its value will be copied into | |
224 | (and referenced from) the free variables vector. | |
225 | ||
226 | @code{foo} is a top-level variable, because @code{foo} is not | |
227 | lexically bound in this example. | |
8680d53b | 228 | |
00ce5125 AW |
229 | @node VM Programs |
230 | @subsection Compiled Procedures are VM Programs | |
8680d53b AW |
231 | |
232 | By default, when you enter in expressions at Guile's REPL, they are | |
23e2e780 AW |
233 | first compiled to bytecode. Then that bytecode is executed to produce a |
234 | value. If the expression evaluates to a procedure, the result of this | |
235 | process is a compiled procedure. | |
236 | ||
237 | A compiled procedure is a compound object consisting of its bytecode and | |
238 | a reference to any captured lexical variables. In addition, when a | |
239 | procedure is compiled, it has associated metadata written to side | |
240 | tables, for instance a line number mapping, or its docstring. You can | |
241 | pick apart these pieces with the accessors in @code{(system vm | |
242 | program)}. @xref{Compiled Procedures}, for a full API reference. | |
243 | ||
244 | A procedure may reference data that was statically allocated when the | |
245 | procedure was compiled. For example, a pair of immediate objects | |
246 | (@pxref{Immediate objects}) can be allocated directly in the memory | |
247 | segment that contains the compiled bytecode, and accessed directly by | |
248 | the bytecode. | |
249 | ||
250 | Another use for statically allocated data is to serve as a cache for a | |
251 | bytecode. Top-level variable lookups are handled in this way. If the | |
252 | @code{toplevel-box} instruction finds that it does not have a cached | |
253 | variable for a top-level reference, it accesses other static data to | |
254 | resolve the reference, and fills in the cache slot. Thereafter all | |
255 | access to the variable goes through the cache cell. The variable's | |
256 | value may change in the future, but the variable itself will not. | |
8680d53b AW |
257 | |
258 | We can see how these concepts tie together by disassembling the | |
81fd3152 | 259 | @code{foo} function we defined earlier to see what is going on: |
8680d53b AW |
260 | |
261 | @smallexample | |
262 | scheme@@(guile-user)> (define (foo a) (lambda (b) (list foo a b))) | |
263 | scheme@@(guile-user)> ,x foo | |
23e2e780 AW |
264 | Disassembly of #<procedure foo (a)> at #x203be34: |
265 | ||
266 | 0 (assert-nargs-ee/locals 2 1) ;; 1 arg, 1 local at (unknown file):1:0 | |
267 | 1 (make-closure 2 6 1) ;; anonymous procedure at #x203be50 (1 free var) | |
268 | 4 (free-set! 2 1 0) ;; free var 0 | |
269 | 6 (return 2) | |
8680d53b AW |
270 | |
271 | ---------------------------------------- | |
23e2e780 AW |
272 | Disassembly of anonymous procedure at #x203be50: |
273 | ||
274 | 0 (assert-nargs-ee/locals 2 3) ;; 1 arg, 3 locals at (unknown file):1:0 | |
275 | 1 (toplevel-box 2 73 57 71 #t) ;; `foo' | |
276 | 6 (box-ref 2 2) | |
277 | 7 (make-short-immediate 3 772) ;; () | |
278 | 8 (cons 3 1 3) | |
279 | 9 (free-ref 4 0 0) ;; free var 0 | |
280 | 11 (cons 3 4 3) | |
281 | 12 (cons 2 2 3) | |
282 | 13 (return 2) | |
8680d53b AW |
283 | @end smallexample |
284 | ||
23e2e780 AW |
285 | First there's some prelude, where @code{foo} checks that it was called |
286 | with only 1 argument. Then at @code{ip} 1, we allocate a new closure | |
287 | and store it in slot 2. The `6' in the @code{(make-closure 2 6 1)} is a | |
288 | relative offset from the instruction pointer of the code for the | |
289 | closure. | |
290 | ||
291 | A closure is code with data. We already have the code part initialized; | |
292 | what remains is to set the data. @code{Ip} 4 initializes free variable | |
293 | 0 in the new closure with the value from local variable 1, which | |
294 | corresponds to the first argument of @code{foo}: `a'. Finally we return | |
295 | the closure. | |
296 | ||
297 | The second stanza disassembles the code for the closure. After the | |
298 | prelude, we load the variable for the toplevel variable @code{foo} into | |
299 | local variable 2. This lookup occurs lazily, the first time the | |
300 | variable is actually referenced, and the location of the lookup is | |
301 | cached so that future references are very cheap. @xref{Top-Level | |
302 | Environment Instructions}, for more details. The @code{box-ref} | |
303 | dereferences the variable cell, replacing the contents of local 2. | |
304 | ||
305 | What follows is a sequence of conses to build up the result list. | |
306 | @code{Ip} 7 makes the tail of the list. @code{Ip} 8 conses on the value | |
307 | in local 1, corresponding to the first argument to the closure: `b'. | |
308 | @code{Ip} 9 loads free variable 0 of local 0 -- the procedure being | |
309 | called -- into slot 4, then @code{ip} 11 conses it onto the list. | |
310 | Finally we cons local 2, containing the @code{foo} toplevel, onto the | |
311 | front of the list, and we return it. | |
8680d53b | 312 | |
1f6f591d AW |
313 | |
314 | @node Object File Format | |
315 | @subsection Object File Format | |
316 | ||
317 | To compile a file to disk, we need a format in which to write the | |
318 | compiled code to disk, and later load it into Guile. A good @dfn{object | |
319 | file format} has a number of characteristics: | |
320 | ||
321 | @itemize | |
322 | @item Above all else, it should be very cheap to load a compiled file. | |
323 | @item It should be possible to statically allocate constants in the | |
324 | file. For example, a bytevector literal in source code can be emitted | |
325 | directly into the object file. | |
326 | @item The compiled file should enable maximum code and data sharing | |
327 | between different processes. | |
328 | @item The compiled file should contain debugging information, such as | |
329 | line numbers, but that information should be separated from the code | |
330 | itself. It should be possible to strip debugging information if space | |
331 | is tight. | |
332 | @end itemize | |
333 | ||
334 | These characteristics are not specific to Scheme. Indeed, mainstream | |
335 | languages like C and C++ have solved this issue many times in the past. | |
336 | Guile builds on their work by adopting ELF, the object file format of | |
337 | GNU and other Unix-like systems, as its object file format. Although | |
338 | Guile uses ELF on all platforms, we do not use platform support for ELF. | |
339 | Guile implements its own linker and loader. The advantage of using ELF | |
340 | is not sharing code, but sharing ideas. ELF is simply a well-designed | |
341 | object file format. | |
342 | ||
343 | An ELF file has two meta-tables describing its contents. The first | |
344 | meta-table is for the loader, and is called the @dfn{program table} or | |
345 | sometimes the @dfn{segment table}. The program table divides the file | |
346 | into big chunks that should be treated differently by the loader. | |
347 | Mostly the difference between these @dfn{segments} is their | |
348 | permissions. | |
349 | ||
350 | Typically all segments of an ELF file are marked as read-only, except | |
351 | that part that represents modifiable static data or static data that | |
352 | needs load-time initialization. Loading an ELF file is as simple as | |
353 | mmapping the thing into memory with read-only permissions, then using | |
354 | the segment table to mark a small sub-region of the file as writable. | |
355 | This writable section is typically added to the root set of the garbage | |
356 | collector as well. | |
357 | ||
358 | One ELF segment is marked as ``dynamic'', meaning that it has data of | |
359 | interest to the loader. Guile uses this segment to record the Guile | |
360 | version corresponding to this file. There is also an entry in the | |
361 | dynamic segment that points to the address of an initialization thunk | |
362 | that is run to perform any needed link-time initialization. (This is | |
363 | like dynamic relocations for normal ELF shared objects, except that we | |
364 | compile the relocations as a procedure instead of having the loader | |
365 | interpret a table of relocations.) Finally, the dynamic segment marks | |
366 | the location of the ``entry thunk'' of the object file. This thunk is | |
367 | returned to the caller of @code{load-thunk-from-memory} or | |
368 | @code{load-thunk-from-file}. When called, it will execute the ``body'' | |
369 | of the compiled expression. | |
370 | ||
371 | The other meta-table in an ELF file is the @dfn{section table}. Whereas | |
372 | the program table divides an ELF file into big chunks for the loader, | |
373 | the section table specifies small sections for use by introspective | |
374 | tools like debuggers or the like. One segment (program table entry) | |
375 | typically contains many sections. There may be sections outside of any | |
376 | segment, as well. | |
377 | ||
378 | Typical sections in a Guile @code{.go} file include: | |
379 | ||
380 | @table @code | |
381 | @item .rtl-text | |
382 | Bytecode. | |
383 | @item .data | |
384 | Data that needs initialization, or which may be modified at runtime. | |
385 | @item .rodata | |
386 | Statically allocated data that needs no run-time initialization, and | |
387 | which therefore can be shared between processes. | |
388 | @item .dynamic | |
389 | The dynamic section, discussed above. | |
390 | @item .symtab | |
391 | @itemx .strtab | |
392 | A table mapping addresses in the @code{.rtl-text} to procedure names. | |
393 | @code{.strtab} is used by @code{.symtab}. | |
394 | @item .guile.procprops | |
395 | @itemx .guile.arities | |
396 | @itemx .guile.arities.strtab | |
397 | @itemx .guile.docstrs | |
398 | @itemx .guile.docstrs.strtab | |
399 | Side tables of procedure properties, arities, and docstrings. | |
400 | @item .debug_info | |
401 | @itemx .debug_abbrev | |
402 | @itemx .debug_str | |
403 | @itemx .debug_loc | |
404 | @itemx .debug_line | |
405 | Debugging information, in DWARF format. See the DWARF specification, | |
406 | for more information. | |
407 | @item .shstrtab | |
408 | Section name string table. | |
409 | @end table | |
410 | ||
411 | For more information, see @uref{http://linux.die.net/man/5/elf,,the | |
412 | elf(5) man page}. See @uref{http://dwarfstd.org/,the DWARF | |
413 | specification} for more on the DWARF debugging format. Or if you are an | |
414 | adventurous explorer, try running @code{readelf} or @code{objdump} on | |
415 | compiled @code{.go} files. It's good times! | |
416 | ||
417 | ||
8680d53b AW |
418 | @node Instruction Set |
419 | @subsection Instruction Set | |
420 | ||
23e2e780 AW |
421 | There are currently about 130 instructions in Guile's virtual machine. |
422 | These instructions represent atomic units of a program's execution. | |
423 | Ideally, they perform one task without conditional branches, then | |
424 | dispatch to the next instruction in the stream. | |
425 | ||
426 | Instructions themselves are composed of 1 or more 32-bit units. The low | |
427 | 8 bits of the first word indicate the opcode, and the rest of | |
428 | instruction describe the operands. There are a number of different ways | |
429 | operands can be encoded. | |
430 | ||
431 | @table @code | |
432 | @item u@var{n} | |
433 | An unsigned @var{n}-bit integer. Usually indicates the index of a local | |
434 | variable, but some instructions interpret these operands as immediate | |
435 | values. | |
436 | @item l24 | |
437 | An offset from the current @code{ip}, in 32-bit units, as a signed | |
438 | 24-bit value. Indicates a bytecode address, for a relative jump. | |
439 | @item i16 | |
440 | @itemx i32 | |
441 | An immediate Scheme value (@pxref{Immediate objects}), encoded directly | |
442 | in 16 or 32 bits. | |
443 | @item a32 | |
444 | @itemx b32 | |
445 | An immediate Scheme value, encoded as a pair of 32-bit words. | |
446 | @code{a32} and @code{b32} values always go together on the same opcode, | |
447 | and indicate the high and low bits, respectively. Normally only used on | |
448 | 64-bit systems. | |
449 | @item n32 | |
450 | A statically allocated non-immediate. The address of the non-immediate | |
451 | is encoded as a signed 32-bit integer, and indicates a relative offset | |
452 | in 32-bit units. Think of it as @code{SCM x = ip + offset}. | |
453 | @item s32 | |
454 | Indirect scheme value, like @code{n32} but indirected. Think of it as | |
455 | @code{SCM *x = ip + offset}. | |
456 | @item l32 | |
457 | @item lo32 | |
458 | An ip-relative address, as a signed 32-bit integer. Could indicate a | |
459 | bytecode address, as in @code{make-closure}, or a non-immediate address, | |
460 | as with @code{static-patch!}. | |
461 | ||
462 | @code{l32} and @code{lo32} are the same from the perspective of the | |
463 | virtual machine. The difference is that an assembler might want to | |
464 | allow an @code{lo32} address to be specified as a label and then some | |
465 | number of words offset from that label, for example when patching a | |
466 | field of a statically allocated object. | |
467 | @item b1 | |
468 | A boolean value: 1 for true, otherwise 0. | |
469 | @item x@var{n} | |
470 | An ignored sequence of @var{n} bits. | |
471 | @end table | |
472 | ||
473 | An instruction is specified by giving its name, then describing its | |
474 | operands. The operands are packed by 32-bit words, with earlier | |
475 | operands occupying the lower bits. | |
476 | ||
477 | For example, consider the following instruction specification: | |
478 | ||
479 | @deftypefn Instruction {} free-set! u12:@var{dst} u12:@var{src} x8:@var{_} u24:@var{idx} | |
480 | Set free variable @var{idx} from the closure @var{dst} to @var{src}. | |
481 | @end deftypefn | |
bd7aa35f | 482 | |
23e2e780 AW |
483 | The first word in the instruction will start with the 8-bit value |
484 | corresponding to the @var{free-set!} opcode in the low bits, followed by | |
485 | @var{dst} and @var{src} as 12-bit values. The second word starts with 8 | |
486 | dead bits, followed by the index as a 24-bit immediate value. | |
bd7aa35f AW |
487 | |
488 | Sometimes the compiler can figure out that it is compiling a special | |
489 | case that can be run more efficiently. So, for example, while Guile | |
490 | offers a generic test-and-branch instruction, it also offers specific | |
491 | instructions for special cases, so that the following cases all have | |
492 | their own test-and-branch instructions: | |
493 | ||
494 | @example | |
495 | (if pred then else) | |
496 | (if (not pred) then else) | |
497 | (if (null? l) then else) | |
498 | (if (not (null? l)) then else) | |
499 | @end example | |
500 | ||
501 | In addition, some Scheme primitives have their own inline | |
23e2e780 AW |
502 | implementations. For example, in the previous section we saw |
503 | @code{cons}. | |
bd7aa35f | 504 | |
23e2e780 AW |
505 | Guile's instruction set is a @emph{complete} instruction set, in that it |
506 | provides the instructions that are suited to the problem, and is not | |
507 | concerned with making a minimal, orthogonal set of instructions. More | |
508 | instructions may be added over time. | |
8680d53b AW |
509 | |
510 | @menu | |
69aecc6a AW |
511 | * Lexical Environment Instructions:: |
512 | * Top-Level Environment Instructions:: | |
513 | * Procedure Call and Return Instructions:: | |
514 | * Function Prologue Instructions:: | |
515 | * Trampoline Instructions:: | |
516 | * Branch Instructions:: | |
517 | * Constant Instructions:: | |
518 | * Dynamic Environment Instructions:: | |
519 | * Miscellaneous Instructions:: | |
520 | * Inlined Scheme Instructions:: | |
521 | * Inlined Mathematical Instructions:: | |
522 | * Inlined Bytevector Instructions:: | |
8680d53b AW |
523 | @end menu |
524 | ||
8680d53b | 525 | |
acc51c3e AW |
526 | @node Lexical Environment Instructions |
527 | @subsubsection Lexical Environment Instructions | |
528 | ||
529 | These instructions access and mutate the lexical environment of a | |
69aecc6a AW |
530 | compiled procedure---its free and bound variables. @xref{Stack Layout}, |
531 | for more information on the format of stack frames. | |
532 | ||
533 | @deftypefn Instruction {} mov u12:@var{dst} u12:@var{src} | |
534 | @deftypefnx Instruction {} long-mov u24:@var{dst} x8:@var{_} u24:@var{src} | |
535 | Copy a value from one local slot to another. | |
536 | ||
537 | As discussed previously, procedure arguments and local variables are | |
538 | allocated to local slots. Guile's compiler tries to avoid shuffling | |
539 | variables around to different slots, which often makes @code{mov} | |
540 | instructions redundant. However there are some cases in which shuffling | |
541 | is necessary, and in those cases, @code{mov} is the thing to use. | |
542 | @end deftypefn | |
543 | ||
544 | @deftypefn Instruction {} make-closure u24:@var{dst} l32:@var{offset} x8:@var{_} u24:@var{nfree} | |
545 | Make a new closure, and write it to @var{dst}. The code for the closure | |
546 | will be found at @var{offset} words from the current @code{ip}. | |
547 | @var{offset} is a signed 32-bit integer. Space for @var{nfree} free | |
548 | variables will be allocated. | |
549 | ||
550 | The size of a closure is currently two words, plus one word per free | |
551 | variable. | |
552 | @end deftypefn | |
553 | ||
554 | @deftypefn Instruction {} free-ref u12:@var{dst} u12:@var{src} x8:@var{_} u24:@var{idx} | |
555 | Load free variable @var{idx} from the closure @var{src} into local slot | |
556 | @var{dst}. | |
557 | @end deftypefn | |
558 | ||
559 | @deftypefn Instruction {} free-set! u12:@var{dst} u12:@var{src} x8:@var{_} u24:@var{idx} | |
560 | Set free variable @var{idx} from the closure @var{dst} to @var{src}. | |
561 | ||
562 | This instruction is usually used when initializing a closure's free | |
563 | variables, but not to mutate free variables, as variables that are | |
564 | assigned are boxed. | |
565 | @end deftypefn | |
566 | ||
567 | Recall that variables that are assigned are usually allocated in boxes, | |
568 | so that continuations and closures can capture their identity and not | |
569 | their value at one point in time. Variables are also used in the | |
570 | implementation of top-level bindings; see the next section for more | |
571 | information. | |
572 | ||
573 | @deftypefn Instruction {} box u12:@var{dst} u12:@var{src} | |
574 | Create a new variable holding @var{src}, and place it in @var{dst}. | |
575 | @end deftypefn | |
576 | ||
577 | @deftypefn Instruction {} box-ref u12:@var{dst} u12:@var{src} | |
578 | Unpack the variable at @var{src} into @var{dst}, asserting that the | |
579 | variable is actually bound. | |
580 | @end deftypefn | |
581 | ||
582 | @deftypefn Instruction {} box-set! u12:@var{dst} u12:@var{src} | |
583 | Set the contents of the variable at @var{dst} to @var{set}. | |
584 | @end deftypefn | |
98850fd7 | 585 | |
acc51c3e AW |
586 | |
587 | @node Top-Level Environment Instructions | |
588 | @subsubsection Top-Level Environment Instructions | |
589 | ||
590 | These instructions access values in the top-level environment: bindings | |
591 | that were not lexically apparent at the time that the code in question | |
592 | was compiled. | |
593 | ||
594 | The location in which a toplevel binding is stored can be looked up once | |
595 | and cached for later. The binding itself may change over time, but its | |
596 | location will stay constant. | |
597 | ||
69aecc6a AW |
598 | @deftypefn Instruction {} current-module u24:@var{dst} |
599 | Store the current module in @var{dst}. | |
600 | @end deftypefn | |
601 | ||
602 | @deftypefn Instruction {} resolve u24:@var{dst} b1:@var{bound?} x7:@var{_} u24:@var{sym} | |
603 | Resolve @var{sym} in the current module, and place the resulting | |
604 | variable in @var{dst}. An error will be signalled if no variable is | |
605 | found. If @var{bound?} is true, an error will be signalled if the | |
606 | variable is unbound. | |
607 | @end deftypefn | |
608 | ||
609 | @deftypefn Instruction {} define! u12:@var{sym} u12:@var{val} | |
610 | Look up a binding for @var{sym} in the current module, creating it if | |
611 | necessary. Set its value to @var{val}. | |
612 | @end deftypefn | |
613 | ||
614 | @deftypefn Instruction {} toplevel-box u24:@var{dst} s32:@var{var-offset} s32:@var{mod-offset} n32:@var{sym-offset} b1:@var{bound?} x31:@var{_} | |
615 | Load a value. The value will be fetched from memory, @var{var-offset} | |
616 | 32-bit words away from the current instruction pointer. | |
617 | @var{var-offset} is a signed value. Up to here, @code{toplevel-box} is | |
618 | like @code{static-ref}. | |
619 | ||
620 | Then, if the loaded value is a variable, it is placed in @var{dst}, and | |
621 | control flow continues. | |
622 | ||
623 | Otherwise, we have to resolve the variable. In that case we load the | |
624 | module from @var{mod-offset}, just as we loaded the variable. Usually | |
625 | the module gets set when the closure is created. @var{sym-offset} | |
626 | specifies the name, as an offset to a symbol. | |
627 | ||
628 | We use the module and the symbol to resolve the variable, placing it in | |
629 | @var{dst}, and caching the resolved variable so that we will hit the | |
630 | cache next time. If @var{bound?} is true, an error will be signalled if | |
631 | the variable is unbound. | |
632 | @end deftypefn | |
633 | ||
634 | @deftypefn Instruction {} module-box u24:@var{dst} s32:@var{var-offset} n32:@var{mod-offset} n32:@var{sym-offset} b1:@var{bound?} x31:@var{_} | |
635 | Like @code{toplevel-box}, except @var{mod-offset} points at a module | |
636 | identifier instead of the module itself. A module identifier is a | |
637 | module name, as a list, prefixed by a boolean. If the prefix is true, | |
638 | then the variable is resolved relative to the module's public interface | |
639 | instead of its private interface. | |
640 | @end deftypefn | |
98850fd7 | 641 | |
81fd3152 | 642 | |
acc51c3e AW |
643 | @node Procedure Call and Return Instructions |
644 | @subsubsection Procedure Call and Return Instructions | |
8680d53b | 645 | |
69aecc6a AW |
646 | As described earlier (@pxref{Stack Layout}), Guile's calling convention |
647 | is that arguments are passed and values returned on the stack. | |
648 | ||
649 | For calls, both in tail position and in non-tail position, we require | |
650 | that the procedure and the arguments already be shuffled into place | |
651 | befor the call instruction. ``Into place'' for a tail call means that | |
652 | the procedure should be in slot 0, and the arguments should follow. For | |
653 | a non-tail call, if the procedure is in slot @var{n}, the arguments | |
654 | should follow from slot @var{n}+1, and there should be two free slots at | |
655 | @var{n}-1 and @var{n}-2 in which to save the @code{ip} and @code{fp}. | |
656 | ||
657 | Returning values is similar. Multiple-value returns should have values | |
658 | already shuffled down to start from slot 1 before emitting | |
659 | @code{return-values}. There is a short-cut in the single-value case, in | |
660 | that @code{return} handles the trivial shuffling itself. We start from | |
661 | slot 1 instead of slot 0 to make tail calls to @code{values} trivial. | |
662 | ||
663 | In both calls and returns, the @code{sp} is used to indicate to the | |
664 | callee or caller the number of arguments or return values, respectively. | |
665 | After receiving return values, it is the caller's responsibility to | |
666 | @dfn{restore the frame} by resetting the @code{sp} to its former value. | |
667 | ||
668 | @deftypefn Instruction {} call u24:@var{proc} x8:@var{_} u24:@var{nlocals} | |
669 | Call a procedure. @var{proc} is the local corresponding to a procedure. | |
670 | The two values below @var{proc} will be overwritten by the saved call | |
671 | frame data. The new frame will have space for @var{nlocals} locals: one | |
672 | for the procedure, and the rest for the arguments which should already | |
673 | have been pushed on. | |
674 | ||
675 | When the call returns, execution proceeds with the next instruction. | |
676 | There may be any number of values on the return stack; the precise | |
677 | number can be had by subtracting the address of @var{proc} from the | |
678 | post-call @code{sp}. | |
679 | @end deftypefn | |
680 | ||
681 | @deftypefn Instruction {} tail-call u24:@var{nlocals} | |
682 | Tail-call a procedure. Requires that the procedure and all of the | |
683 | arguments have already been shuffled into position. Will reset the | |
684 | frame to @var{nlocals}. | |
685 | @end deftypefn | |
686 | ||
687 | @deftypefn Instruction {} tail-call/shuffle u24:@var{from} | |
688 | Tail-call a procedure. The procedure should already be set to slot 0. | |
689 | The rest of the args are taken from the frame, starting at @var{from}, | |
690 | shuffled down to start at slot 0. This is part of the implementation of | |
691 | the @code{call-with-values} builtin. | |
692 | @end deftypefn | |
693 | ||
694 | @deftypefn Instruction {} receive u12:@var{dst} u12:@var{proc} x8:@var{_} u24:@var{nlocals} | |
695 | Receive a single return value from a call whose procedure was in | |
696 | @var{proc}, asserting that the call actually returned at least one | |
697 | value. Afterwards, resets the frame to @var{nlocals} locals. | |
698 | @end deftypefn | |
699 | ||
700 | @deftypefn Instruction {} receive-values u24:@var{proc} b1:@var{allow-extra?} x7:@var{_} u24:@var{nvalues} | |
701 | Receive a return of multiple values from a call whose procedure was in | |
702 | @var{proc}. If fewer than @var{nvalues} values were returned, signal an | |
703 | error. Unless @var{allow-extra?} is true, require that the number of | |
704 | return values equals @var{nvalues} exactly. After @code{receive-values} | |
705 | has run, the values can be copied down via @code{mov}, or used in place. | |
706 | @end deftypefn | |
707 | ||
708 | @deftypefn Instruction {} return u24:@var{src} | |
709 | Return a value. | |
710 | @end deftypefn | |
711 | ||
712 | @deftypefn Instruction {} return-values x24:@var{_} | |
713 | Return a number of values from a call frame. This opcode corresponds to | |
714 | an application of @code{values} in tail position. As with tail calls, | |
715 | we expect that the values have already been shuffled down to a | |
716 | contiguous array starting at slot 1. We also expect the frame has | |
717 | already been reset. | |
718 | @end deftypefn | |
719 | ||
720 | @deftypefn Instruction {} call/cc x24:@var{_} | |
721 | Capture the current continuation, and tail-apply the procedure in local | |
722 | slot 1 to it. This instruction is part of the implementation of | |
723 | @code{call/cc}, and is not generated by the compiler. | |
724 | @end deftypefn | |
8274228f | 725 | |
8680d53b | 726 | |
acc51c3e AW |
727 | @node Function Prologue Instructions |
728 | @subsubsection Function Prologue Instructions | |
729 | ||
730 | A function call in Guile is very cheap: the VM simply hands control to | |
731 | the procedure. The procedure itself is responsible for asserting that it | |
732 | has been passed an appropriate number of arguments. This strategy allows | |
733 | arbitrarily complex argument parsing idioms to be developed, without | |
734 | harming the common case. | |
735 | ||
736 | For example, only calls to keyword-argument procedures ``pay'' for the | |
737 | cost of parsing keyword arguments. (At the time of this writing, calling | |
738 | procedures with keyword arguments is typically two to four times as | |
739 | costly as calling procedures with a fixed set of arguments.) | |
740 | ||
69aecc6a AW |
741 | @deftypefn Instruction {} assert-nargs-ee u24:@var{expected} |
742 | @deftypefnx Instruction {} assert-nargs-ge u24:@var{expected} | |
743 | @deftypefnx Instruction {} assert-nargs-le u24:@var{expected} | |
744 | If the number of actual arguments is not @code{==}, @code{>=}, or | |
745 | @code{<=} @var{expected}, respectively, signal an error. | |
acc51c3e AW |
746 | |
747 | The number of arguments is determined by subtracting the frame pointer | |
69aecc6a AW |
748 | from the stack pointer (@code{sp + 1 - fp}). @xref{Stack Layout}, for |
749 | more details on stack frames. Note that @var{expected} includes the | |
750 | procedure itself. | |
751 | @end deftypefn | |
acc51c3e | 752 | |
69aecc6a AW |
753 | @deftypefn Instruction {} br-if-nargs-ne u24:@var{expected} x8:@var{_} l24:@var{offset} |
754 | @deftypefnx Instruction {} br-if-nargs-lt u24:@var{expected} x8:@var{_} l24:@var{offset} | |
755 | @deftypefnx Instruction {} br-if-nargs-gt u24:@var{expected} x8:@var{_} l24:@var{offset} | |
756 | If the number of actual arguments is not equal, less than, or greater | |
757 | than @var{expected}, respectively, add @var{offset}, a signed 24-bit | |
758 | number, to the current instruction pointer. Note that @var{expected} | |
759 | includes the procedure itself. | |
acc51c3e | 760 | |
ecb87335 | 761 | These instructions are used to implement multiple arities, as in |
acc51c3e | 762 | @code{case-lambda}. @xref{Case-lambda}, for more information. |
69aecc6a AW |
763 | @end deftypefn |
764 | ||
765 | @deftypefn Instruction {} alloc-frame u24:@var{nlocals} | |
766 | Ensure that there is space on the stack for @var{nlocals} local | |
767 | variables, setting them all to @code{SCM_UNDEFINED}, except those values | |
768 | that are already on the stack. | |
769 | @end deftypefn | |
770 | ||
771 | @deftypefn Instruction {} reset-frame u24:@var{nlocals} | |
772 | Like @code{alloc-frame}, but doesn't check that the stack is big enough, | |
773 | and doesn't initialize values to @code{SCM_UNDEFINED}. Used to reset | |
774 | the frame size to something less than the size that was previously set | |
775 | via alloc-frame. | |
776 | @end deftypefn | |
777 | ||
778 | @deftypefn Instruction {} assert-nargs-ee/locals u12:@var{expected} u12:@var{nlocals} | |
779 | Equivalent to a sequence of @code{assert-nargs-ee} and | |
780 | @code{reserve-locals}. The number of locals reserved is @var{expected} | |
781 | + @var{nlocals}. | |
782 | @end deftypefn | |
783 | ||
784 | @deftypefn Instruction {} br-if-npos-gt u24:@var{nreq} x8:@var{_} u24:@var{npos} x8:@var{_} l24:@var{offset} | |
785 | Find the first positional argument after @var{nreq}. If it is greater | |
786 | than @var{npos}, jump to @var{offset}. | |
787 | ||
788 | This instruction is only emitted for functions with multiple clauses, | |
789 | and an earlier clause has keywords and no rest arguments. | |
790 | @xref{Case-lambda}, for more on how @code{case-lambda} chooses the | |
791 | clause to apply. | |
792 | @end deftypefn | |
793 | ||
794 | @deftypefn Instruction {} bind-kwargs u24:@var{nreq} u8:@var{flags} u24:@var{nreq-and-opt} x8:@var{_} u24:@var{ntotal} n32:@var{kw-offset} | |
795 | @var{flags} is a bitfield, whose lowest bit is @var{allow-other-keys}, | |
796 | second bit is @var{has-rest}, and whose following six bits are unused. | |
797 | ||
798 | Find the last positional argument, and shuffle all the rest above | |
799 | @var{ntotal}. Initialize the intervening locals to | |
800 | @code{SCM_UNDEFINED}. Then load the constant at @var{kw-offset} words | |
801 | from the current @var{ip}, and use it and the @var{allow-other-keys} | |
802 | flag to bind keyword arguments. If @var{has-rest}, collect all shuffled | |
803 | arguments into a list, and store it in @var{nreq-and-opt}. Finally, | |
804 | clear the arguments that we shuffled up. | |
acc51c3e AW |
805 | |
806 | The parsing is driven by a keyword arguments association list, looked up | |
69aecc6a AW |
807 | using @var{kw-offset}. The alist is a list of pairs of the form |
808 | @code{(@var{kw} . @var{index})}, mapping keyword arguments to their | |
809 | local slot indices. Unless @code{allow-other-keys} is set, the parser | |
810 | will signal an error if an unknown key is found. | |
811 | ||
812 | A macro-mega-instruction. | |
813 | @end deftypefn | |
814 | ||
815 | @deftypefn Instruction {} bind-rest u24:@var{dst} | |
816 | Collect any arguments at or above @var{dst} into a list, and store that | |
817 | list at @var{dst}. | |
818 | @end deftypefn | |
de45d8ee | 819 | |
acc51c3e AW |
820 | |
821 | @node Trampoline Instructions | |
822 | @subsubsection Trampoline Instructions | |
823 | ||
69aecc6a AW |
824 | Though most applicable objects in Guile are procedures implemented in |
825 | bytecode, not all are. There are primitives, continuations, and other | |
826 | procedure-like objects that have their own calling convention. Instead | |
acc51c3e AW |
827 | of adding special cases to the @code{call} instruction, Guile wraps |
828 | these other applicable objects in VM trampoline procedures, then | |
829 | provides special support for these objects in bytecode. | |
830 | ||
831 | Trampoline procedures are typically generated by Guile at runtime, for | |
69aecc6a AW |
832 | example in response to a call to @code{scm_c_make_gsubr}. As such, a |
833 | compiler probably shouldn't emit code with these instructions. However, | |
acc51c3e AW |
834 | it's still interesting to know how these things work, so we document |
835 | these trampoline instructions here. | |
836 | ||
69aecc6a AW |
837 | @deftypefn Instruction {} subr-call u24:@var{ptr-idx} |
838 | Call a subr, passing all locals in this frame as arguments. Fetch the | |
839 | foreign pointer from @var{ptr-idx}, a free variable. Return from the | |
840 | calling frame. | |
841 | @end deftypefn | |
acc51c3e | 842 | |
69aecc6a AW |
843 | @deftypefn Instruction {} foreign-call u12:@var{cif-idx} u12:@var{ptr-idx} |
844 | Call a foreign function. Fetch the @var{cif} and foreign pointer from | |
845 | @var{cif-idx} and @var{ptr-idx}, both free variables. Return from the calling | |
846 | frame. Arguments are taken from the stack. | |
847 | @end deftypefn | |
848 | ||
849 | @deftypefn Instruction {} continuation-call u24:@var{contregs} | |
850 | Return to a continuation, nonlocally. The arguments to the continuation | |
851 | are taken from the stack. @var{contregs} is a free variable containing | |
852 | the reified continuation. | |
853 | @end deftypefn | |
acc51c3e | 854 | |
69aecc6a AW |
855 | @deftypefn Instruction {} compose-continuation u24:@var{cont} |
856 | Compose a partial continution with the current continuation. The | |
857 | arguments to the continuation are taken from the stack. @var{cont} is a | |
858 | free variable containing the reified continuation. | |
859 | @end deftypefn | |
acc51c3e | 860 | |
69aecc6a AW |
861 | @deftypefn Instruction {} tail-apply x24:@var{_} |
862 | Tail-apply the procedure in local slot 0 to the rest of the arguments. | |
863 | This instruction is part of the implementation of @code{apply}, and is | |
864 | not generated by the compiler. | |
865 | @end deftypefn | |
866 | ||
867 | @deftypefn Instruction {} builtin-ref u12:@var{dst} u12:@var{idx} | |
868 | Load a builtin stub by index into @var{dst}. | |
869 | @end deftypefn | |
acc51c3e AW |
870 | |
871 | ||
872 | @node Branch Instructions | |
873 | @subsubsection Branch Instructions | |
874 | ||
69aecc6a AW |
875 | All offsets to branch instructions are 24-bit signed numbers, which |
876 | count 32-bit units. This gives Guile effectively a 26-bit address range | |
877 | for relative jumps. | |
acc51c3e | 878 | |
69aecc6a AW |
879 | @deftypefn Instruction {} br l24:@var{offset} |
880 | Add @var{offset} to the current instruction pointer. | |
881 | @end deftypefn | |
acc51c3e | 882 | |
69aecc6a AW |
883 | All the conditional branch instructions described below have an |
884 | @var{invert} parameter, which if true reverses the test: | |
885 | @code{br-if-true} becomes @code{br-if-false}, and so on. | |
acc51c3e | 886 | |
69aecc6a AW |
887 | @deftypefn Instruction {} br-if-true u24:@var{test} b1:@var{invert} x7:@var{_} l24:@var{offset} |
888 | If the value in @var{test} is true for the purposes of Scheme, add | |
889 | @var{offset} to the current instruction pointer. | |
890 | @end deftypefn | |
891 | ||
892 | @deftypefn Instruction {} br-if-null u24:@var{test} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
893 | If the value in @var{test} is the end-of-list or Lisp nil, add | |
894 | @var{offset} to the current instruction pointer. | |
895 | @end deftypefn | |
896 | ||
897 | @deftypefn Instruction {} br-if-nil u24:@var{test} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
898 | If the value in @var{test} is false to Lisp, add @var{offset} to the | |
899 | current instruction pointer. | |
900 | @end deftypefn | |
901 | ||
902 | @deftypefn Instruction {} br-if-pair u24:@var{test} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
903 | If the value in @var{test} is a pair, add @var{offset} to the current | |
904 | instruction pointer. | |
905 | @end deftypefn | |
906 | ||
907 | @deftypefn Instruction {} br-if-struct u24:@var{test} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
908 | If the value in @var{test} is a struct, add @var{offset} number to the | |
909 | current instruction pointer. | |
910 | @end deftypefn | |
911 | ||
912 | @deftypefn Instruction {} br-if-char u24:@var{test} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
913 | If the value in @var{test} is a char, add @var{offset} to the current | |
914 | instruction pointer. | |
915 | @end deftypefn | |
916 | ||
917 | @deftypefn Instruction {} br-if-tc7 u24:@var{test} b1:@var{invert} u7:@var{tc7} l24:@var{offset} | |
918 | If the value in @var{test} has the TC7 given in the second word, add | |
919 | @var{offset} to the current instruction pointer. TC7 codes are part of | |
920 | the way Guile represents non-immediate objects, and are deep wizardry. | |
921 | See @code{libguile/tags.h} for all the details. | |
922 | @end deftypefn | |
923 | ||
924 | @deftypefn Instruction {} br-if-eq u12:@var{a} u12:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
925 | @deftypefnx Instruction {} br-if-eqv u12:@var{a} u12:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
926 | @deftypefnx Instruction {} br-if-equal u12:@var{a} u12:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
927 | If the value in @var{a} is @code{eq?}, @code{eqv?}, or @code{equal?} to | |
928 | the value in @var{b}, respectively, add @var{offset} to the current | |
929 | instruction pointer. | |
930 | @end deftypefn | |
931 | ||
932 | @deftypefn Instruction {} br-if-= u12:@var{a} u12:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
933 | @deftypefnx Instruction {} br-if-< u12:@var{a} u12:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
934 | @deftypefnx Instruction {} br-if-<= u12:@var{a} u12:@var{b} b1:@var{invert} x7:@var{_} l24:@var{offset} | |
935 | If the value in @var{a} is @code{=}, @code{<}, or @code{<=} to the value | |
936 | in @var{b}, respectively, add @var{offset} to the current instruction | |
937 | pointer. | |
938 | @end deftypefn | |
939 | ||
940 | ||
941 | @node Constant Instructions | |
942 | @subsubsection Constant Instructions | |
943 | ||
944 | The following instructions load literal data into a program. There are | |
945 | two kinds. | |
946 | ||
947 | The first set of instructions loads immediate values. These | |
948 | instructions encode the immediate directly into the instruction stream. | |
949 | ||
950 | @deftypefn Instruction {} make-short-immediate u8:@var{dst} i16:@var{low-bits} | |
951 | Make an immediate whose low bits are @var{low-bits}, and whose top bits are | |
952 | 0. | |
953 | @end deftypefn | |
954 | ||
955 | @deftypefn Instruction {} make-long-immediate u24:@var{dst} i32:@var{low-bits} | |
956 | Make an immediate whose low bits are @var{low-bits}, and whose top bits are | |
957 | 0. | |
958 | @end deftypefn | |
959 | ||
960 | @deftypefn Instruction {} make-long-long-immediate u24:@var{dst} a32:@var{high-bits} b32:@var{low-bits} | |
961 | Make an immediate with @var{high-bits} and @var{low-bits}. | |
962 | @end deftypefn | |
963 | ||
964 | Non-immediate constant literals are referenced either directly or | |
965 | indirectly. For example, Guile knows at compile-time what the layout of | |
966 | a string will be like, and arranges to embed that object directly in the | |
967 | compiled image. A reference to a string will use | |
968 | @code{make-non-immediate} to treat a pointer into the compilation unit | |
969 | as a @code{SCM} value directly. | |
970 | ||
971 | @deftypefn Instruction {} make-non-immediate u24:@var{dst} n32:@var{offset} | |
972 | Load a pointer to statically allocated memory into @var{dst}. The | |
973 | object's memory is will be found @var{offset} 32-bit words away from the | |
974 | current instruction pointer. Whether the object is mutable or immutable | |
975 | depends on where it was allocated by the compiler, and loaded by the | |
976 | loader. | |
977 | @end deftypefn | |
978 | ||
979 | Some objects must be unique across the whole system. This is the case | |
980 | for symbols and keywords. For these objects, Guile arranges to | |
981 | initialize them when the compilation unit is loaded, storing them into a | |
982 | slot in the image. References go indirectly through that slot. | |
983 | @code{static-ref} is used in this case. | |
984 | ||
985 | @deftypefn Instruction {} static-ref u24:@var{dst} s32:@var{offset} | |
986 | Load a @var{scm} value into @var{dst}. The @var{scm} value will be fetched from | |
987 | memory, @var{offset} 32-bit words away from the current instruction | |
988 | pointer. @var{offset} is a signed value. | |
989 | @end deftypefn | |
990 | ||
991 | Fields of non-immediates may need to be fixed up at load time, because | |
992 | we do not know in advance at what address they will be loaded. This is | |
993 | the case, for example, for a pair containing a non-immediate in one of | |
994 | its fields. @code{static-ref} and @code{static-patch!} are used in | |
995 | these situations. | |
996 | ||
997 | @deftypefn Instruction {} static-set! u24:@var{src} lo32:@var{offset} | |
998 | Store a @var{scm} value into memory, @var{offset} 32-bit words away from the | |
999 | current instruction pointer. @var{offset} is a signed value. | |
1000 | @end deftypefn | |
acc51c3e | 1001 | |
69aecc6a AW |
1002 | @deftypefn Instruction {} static-patch! x24:@var{_} lo32:@var{dst-offset} l32:@var{src-offset} |
1003 | Patch a pointer at @var{dst-offset} to point to @var{src-offset}. Both offsets | |
1004 | are signed 32-bit values, indicating a memory address as a number | |
1005 | of 32-bit words away from the current instruction pointer. | |
1006 | @end deftypefn | |
1007 | ||
1008 | Many kinds of literals can be loaded with the above instructions, once | |
1009 | the compiler has prepared the statically allocated data. This is the | |
1010 | case for vectors, strings, uniform vectors, pairs, and procedures with | |
1011 | no free variables. Other kinds of data might need special initializers; | |
1012 | those instructions follow. | |
acc51c3e | 1013 | |
69aecc6a AW |
1014 | @deftypefn Instruction {} string->number u12:@var{dst} u12:@var{src} |
1015 | Parse a string in @var{src} to a number, and store in @var{dst}. | |
1016 | @end deftypefn | |
1017 | ||
1018 | @deftypefn Instruction {} string->symbol u12:@var{dst} u12:@var{src} | |
1019 | Parse a string in @var{src} to a symbol, and store in @var{dst}. | |
1020 | @end deftypefn | |
1021 | ||
1022 | @deftypefn Instruction {} symbol->keyword u12:@var{dst} u12:@var{src} | |
1023 | Make a keyword from the symbol in @var{src}, and store it in @var{dst}. | |
1024 | @end deftypefn | |
1025 | ||
1026 | @deftypefn Instruction {} load-typed-array u8:@var{dst} u8:@var{type} u8:@var{shape} n32:@var{offset} u32:@var{len} | |
1027 | Load the contiguous typed array located at @var{offset} 32-bit words away | |
1028 | from the instruction pointer, and store into @var{dst}. @var{len} is a byte | |
1029 | length. @var{offset} is signed. | |
1030 | @end deftypefn | |
acc51c3e | 1031 | |
acc51c3e AW |
1032 | |
1033 | @node Dynamic Environment Instructions | |
1034 | @subsubsection Dynamic Environment Instructions | |
1035 | ||
1036 | Guile's virtual machine has low-level support for @code{dynamic-wind}, | |
1037 | dynamic binding, and composable prompts and aborts. | |
1038 | ||
69aecc6a AW |
1039 | @deftypefn Instruction {} abort x24:@var{_} |
1040 | Abort to a prompt handler. The tag is expected in slot 1, and the rest | |
1041 | of the values in the frame are returned to the prompt handler. This | |
1042 | corresponds to a tail application of abort-to-prompt. | |
1043 | ||
1044 | If no prompt can be found in the dynamic environment with the given tag, | |
1045 | an error is signalled. Otherwise all arguments are passed to the | |
1046 | prompt's handler, along with the captured continuation, if necessary. | |
1047 | ||
1048 | If the prompt's handler can be proven to not reference the captured | |
1049 | continuation, no continuation is allocated. This decision happens | |
1050 | dynamically, at run-time; the general case is that the continuation may | |
1051 | be captured, and thus resumed. A reinstated continuation will have its | |
1052 | arguments pushed on the stack from slot 1, as if from a multiple-value | |
1053 | return, and control resumes in the caller. Thus to the calling | |
1054 | function, a call to @code{abort-to-prompt} looks like any other function | |
1055 | call. | |
1056 | @end deftypefn | |
1057 | ||
1058 | @deftypefn Instruction {} prompt u24:@var{tag} b1:@var{escape-only?} x7:@var{_} u24:@var{proc-slot} x8:@var{_} l24:@var{handler-offset} | |
1059 | Push a new prompt on the dynamic stack, with a tag from @var{tag} and a | |
1060 | handler at @var{handler-offset} words from the current @var{ip}. | |
1061 | ||
1062 | If an abort is made to this prompt, control will jump to the handler. | |
1063 | The handler will expect a multiple-value return as if from a call with | |
1064 | the procedure at @var{proc-slot}, with the reified partial continuation | |
1065 | as the first argument, followed by the values returned to the handler. | |
1066 | If control returns to the handler, the prompt is already popped off by | |
1067 | the abort mechanism. (Guile's @code{prompt} implements Felleisen's | |
1068 | @dfn{--F--} operator.) | |
acc51c3e AW |
1069 | |
1070 | If @var{escape-only?} is nonzero, the prompt will be marked as | |
1071 | escape-only, which allows an abort to this prompt to avoid reifying the | |
1072 | continuation. | |
acc51c3e | 1073 | |
69aecc6a AW |
1074 | @xref{Prompts}, for more information on prompts. |
1075 | @end deftypefn | |
acc51c3e | 1076 | |
69aecc6a AW |
1077 | @deftypefn Instruction {} wind u12:@var{winder} u12:@var{unwinder} |
1078 | Push wind and unwind procedures onto the dynamic stack. Note that | |
1079 | neither are actually called; the compiler should emit calls to wind and | |
1080 | unwind for the normal dynamic-wind control flow. Also note that the | |
1081 | compiler should have inserted checks that they wind and unwind procs are | |
1082 | thunks, if it could not prove that to be the case. @xref{Dynamic Wind}. | |
1083 | @end deftypefn | |
acc51c3e | 1084 | |
69aecc6a AW |
1085 | @deftypefn Instruction {} unwind x24:@var{_} |
1086 | @var{a} normal exit from the dynamic extent of an expression. Pop the top | |
1087 | entry off of the dynamic stack. | |
1088 | @end deftypefn | |
acc51c3e | 1089 | |
69aecc6a AW |
1090 | @deftypefn Instruction {} push-fluid u12:@var{fluid} u12:@var{value} |
1091 | Dynamically bind @var{value} to @var{fluid} by creating a with-fluids | |
1092 | object and pushing that object on the dynamic stack. @xref{Fluids and | |
1093 | Dynamic States}. | |
1094 | @end deftypefn | |
8680d53b | 1095 | |
69aecc6a AW |
1096 | @deftypefn Instruction {} pop-fluid x24:@var{_} |
1097 | Leave the dynamic extent of a @code{with-fluid*} expression, restoring | |
1098 | the fluid to its previous value. @code{push-fluid} should always be | |
1099 | balanced with @code{pop-fluid}. | |
1100 | @end deftypefn | |
8680d53b | 1101 | |
69aecc6a AW |
1102 | @deftypefn Instruction {} fluid-ref u12:@var{dst} u12:@var{src} |
1103 | Reference the fluid in @var{src}, and place the value in @var{dst}. | |
1104 | @end deftypefn | |
bd7aa35f | 1105 | |
69aecc6a AW |
1106 | @deftypefn Instruction {} fluid-set u12:@var{fluid} u12:@var{val} |
1107 | Set the value of the fluid in @var{dst} to the value in @var{src}. | |
1108 | @end deftypefn | |
8680d53b | 1109 | |
8680d53b | 1110 | |
69aecc6a AW |
1111 | @node Miscellaneous Instructions |
1112 | @subsubsection Miscellaneous Instructions | |
8680d53b | 1113 | |
69aecc6a AW |
1114 | @deftypefn Instruction {} halt x24:@var{_} |
1115 | Bring the VM to a halt, returning all the values from the stack. Used | |
1116 | in the ``boot continuation'', which is used when entering the VM from C. | |
1117 | @end deftypefn | |
8680d53b | 1118 | |
8680d53b AW |
1119 | |
1120 | @node Inlined Scheme Instructions | |
1121 | @subsubsection Inlined Scheme Instructions | |
1122 | ||
bd7aa35f | 1123 | The Scheme compiler can recognize the application of standard Scheme |
69aecc6a AW |
1124 | procedures. It tries to inline these small operations to avoid the |
1125 | overhead of creating new stack frames. This allows the compiler to | |
1126 | optimize better. | |
1127 | ||
1128 | @deftypefn Instruction {} make-vector/immediate u8:@var{dst} u8:@var{length} u8:@var{init} | |
1129 | Make a short vector of known size and write it to @var{dst}. The vector | |
1130 | will have space for @var{length} slots, an immediate value. They will | |
1131 | be filled with the value in slot @var{init}. | |
1132 | @end deftypefn | |
1133 | ||
1134 | @deftypefn Instruction {} vector-length u12:@var{dst} u12:@var{src} | |
1135 | Store the length of the vector in @var{src} in @var{dst}. | |
1136 | @end deftypefn | |
1137 | ||
1138 | @deftypefn Instruction {} vector-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1139 | Fetch the item at position @var{idx} in the vector in @var{src}, and | |
1140 | store it in @var{dst}. | |
1141 | @end deftypefn | |
1142 | ||
1143 | @deftypefn Instruction {} vector-ref/immediate u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1144 | Fill @var{dst} with the item @var{idx} elements into the vector at | |
1145 | @var{src}. Useful for building data types using vectors. | |
1146 | @end deftypefn | |
1147 | ||
1148 | @deftypefn Instruction {} vector-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1149 | Store @var{src} into the vector @var{dst} at index @var{idx}. | |
1150 | @end deftypefn | |
1151 | ||
1152 | @deftypefn Instruction {} vector-set!/immediate u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1153 | Store @var{src} into the vector @var{dst} at index @var{idx}. Here | |
1154 | @var{idx} is an immediate value. | |
1155 | @end deftypefn | |
1156 | ||
1157 | @deftypefn Instruction {} struct-vtable u12:@var{dst} u12:@var{src} | |
1158 | Store the vtable of @var{src} into @var{dst}. | |
1159 | @end deftypefn | |
1160 | ||
1161 | @deftypefn Instruction {} allocate-struct/immediate u8:@var{dst} u8:@var{vtable} u8:@var{nfields} | |
1162 | Allocate a new struct with @var{vtable}, and place it in @var{dst}. The | |
1163 | struct will be constructed with space for @var{nfields} fields, which | |
1164 | should correspond to the field count of the @var{vtable}. | |
1165 | @end deftypefn | |
1166 | ||
1167 | @deftypefn Instruction {} struct-ref/immediate u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1168 | Fetch the item at slot @var{idx} in the struct in @var{src}, and store | |
1169 | it in @var{dst}. @var{idx} is an immediate unsigned 8-bit value. | |
1170 | @end deftypefn | |
1171 | ||
1172 | @deftypefn Instruction {} struct-set!/immediate u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1173 | Store @var{src} into the struct @var{dst} at slot @var{idx}. @var{idx} | |
1174 | is an immediate unsigned 8-bit value. | |
1175 | @end deftypefn | |
1176 | ||
1177 | @deftypefn Instruction {} class-of u12:@var{dst} u12:@var{type} | |
1178 | Store the vtable of @var{src} into @var{dst}. | |
1179 | @end deftypefn | |
1180 | ||
1181 | @deftypefn Instruction {} make-array u12:@var{dst} u12:@var{type} x8:@var{_} u12:@var{fill} u12:@var{bounds} | |
1182 | Make a new array with @var{type}, @var{fill}, and @var{bounds}, storing it in @var{dst}. | |
1183 | @end deftypefn | |
1184 | ||
1185 | @deftypefn Instruction {} string-length u12:@var{dst} u12:@var{src} | |
1186 | Store the length of the string in @var{src} in @var{dst}. | |
1187 | @end deftypefn | |
1188 | ||
1189 | @deftypefn Instruction {} string-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1190 | Fetch the character at position @var{idx} in the string in @var{src}, and store | |
1191 | it in @var{dst}. | |
1192 | @end deftypefn | |
1193 | ||
1194 | @deftypefn Instruction {} cons u8:@var{dst} u8:@var{car} u8:@var{cdr} | |
1195 | Cons @var{car} and @var{cdr}, and store the result in @var{dst}. | |
1196 | @end deftypefn | |
1197 | ||
1198 | @deftypefn Instruction {} car u12:@var{dst} u12:@var{src} | |
1199 | Place the car of @var{src} in @var{dst}. | |
1200 | @end deftypefn | |
1201 | ||
1202 | @deftypefn Instruction {} cdr u12:@var{dst} u12:@var{src} | |
1203 | Place the cdr of @var{src} in @var{dst}. | |
1204 | @end deftypefn | |
1205 | ||
1206 | @deftypefn Instruction {} set-car! u12:@var{pair} u12:@var{car} | |
1207 | Set the car of @var{dst} to @var{src}. | |
1208 | @end deftypefn | |
1209 | ||
1210 | @deftypefn Instruction {} set-cdr! u12:@var{pair} u12:@var{cdr} | |
1211 | Set the cdr of @var{dst} to @var{src}. | |
1212 | @end deftypefn | |
bd7aa35f AW |
1213 | |
1214 | Note that @code{caddr} and friends compile to a series of @code{car} | |
1215 | and @code{cdr} instructions. | |
8680d53b | 1216 | |
69aecc6a | 1217 | |
8680d53b AW |
1218 | @node Inlined Mathematical Instructions |
1219 | @subsubsection Inlined Mathematical Instructions | |
1220 | ||
bd7aa35f AW |
1221 | Inlining mathematical operations has the obvious advantage of handling |
1222 | fixnums without function calls or allocations. The trick, of course, | |
1223 | is knowing when the result of an operation will be a fixnum, and there | |
1224 | might be a couple bugs here. | |
1225 | ||
1226 | More instructions could be added here over time. | |
1227 | ||
69aecc6a AW |
1228 | All of these operations place their result in their first operand, |
1229 | @var{dst}. | |
1230 | ||
1231 | @deftypefn Instruction {} add u8:@var{dst} u8:@var{a} u8:@var{b} | |
1232 | Add @var{a} to @var{b}. | |
1233 | @end deftypefn | |
1234 | ||
1235 | @deftypefn Instruction {} add1 u12:@var{dst} u12:@var{src} | |
1236 | Add 1 to the value in @var{src}. | |
1237 | @end deftypefn | |
1238 | ||
1239 | @deftypefn Instruction {} sub u8:@var{dst} u8:@var{a} u8:@var{b} | |
1240 | Subtract @var{b} from @var{a}. | |
1241 | @end deftypefn | |
1242 | ||
1243 | @deftypefn Instruction {} sub1 u12:@var{dst} u12:@var{src} | |
1244 | Subtract 1 from @var{src}. | |
1245 | @end deftypefn | |
1246 | ||
1247 | @deftypefn Instruction {} mul u8:@var{dst} u8:@var{a} u8:@var{b} | |
1248 | Multiply @var{a} and @var{b}. | |
1249 | @end deftypefn | |
1250 | ||
1251 | @deftypefn Instruction {} div u8:@var{dst} u8:@var{a} u8:@var{b} | |
1252 | Divide @var{a} by @var{b}. | |
1253 | @end deftypefn | |
1254 | ||
1255 | @deftypefn Instruction {} quo u8:@var{dst} u8:@var{a} u8:@var{b} | |
1256 | Divide @var{a} by @var{b}. | |
1257 | @end deftypefn | |
1258 | ||
1259 | @deftypefn Instruction {} rem u8:@var{dst} u8:@var{a} u8:@var{b} | |
1260 | Divide @var{a} by @var{b}. | |
1261 | @end deftypefn | |
1262 | ||
1263 | @deftypefn Instruction {} mod u8:@var{dst} u8:@var{a} u8:@var{b} | |
1264 | Compute the modulo of @var{a} by @var{b}. | |
1265 | @end deftypefn | |
1266 | ||
1267 | @deftypefn Instruction {} ash u8:@var{dst} u8:@var{a} u8:@var{b} | |
1268 | Shift @var{a} arithmetically by @var{b} bits. | |
1269 | @end deftypefn | |
1270 | ||
1271 | @deftypefn Instruction {} logand u8:@var{dst} u8:@var{a} u8:@var{b} | |
1272 | Compute the bitwise @code{and} of @var{a} and @var{b}. | |
1273 | @end deftypefn | |
1274 | ||
1275 | @deftypefn Instruction {} logior u8:@var{dst} u8:@var{a} u8:@var{b} | |
1276 | Compute the bitwise inclusive @code{or} of @var{a} with @var{b}. | |
1277 | @end deftypefn | |
1278 | ||
1279 | @deftypefn Instruction {} logxor u8:@var{dst} u8:@var{a} u8:@var{b} | |
1280 | Compute the bitwise exclusive @code{or} of @var{a} with @var{b}. | |
1281 | @end deftypefn | |
1282 | ||
98850fd7 AW |
1283 | |
1284 | @node Inlined Bytevector Instructions | |
1285 | @subsubsection Inlined Bytevector Instructions | |
1286 | ||
1287 | Bytevector operations correspond closely to what the current hardware | |
1288 | can do, so it makes sense to inline them to VM instructions, providing | |
1289 | a clear path for eventual native compilation. Without this, Scheme | |
1290 | programs would need other primitives for accessing raw bytes -- but | |
1291 | these primitives are as good as any. | |
1292 | ||
69aecc6a AW |
1293 | @deftypefn Instruction {} bv-u8-ref u8:@var{dst} u8:@var{src} u8:@var{idx} |
1294 | @deftypefnx Instruction {} bv-s8-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1295 | @deftypefnx Instruction {} bv-u16-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1296 | @deftypefnx Instruction {} bv-s16-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1297 | @deftypefnx Instruction {} bv-u32-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1298 | @deftypefnx Instruction {} bv-s32-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1299 | @deftypefnx Instruction {} bv-u64-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1300 | @deftypefnx Instruction {} bv-s64-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1301 | @deftypefnx Instruction {} bv-f32-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1302 | @deftypefnx Instruction {} bv-f64-ref u8:@var{dst} u8:@var{src} u8:@var{idx} | |
1303 | ||
1304 | Fetch the item at byte offset @var{idx} in the bytevector @var{src}, and | |
1305 | store it in @var{dst}. All accesses use native endianness. | |
1306 | @end deftypefn | |
1307 | ||
1308 | @deftypefn Instruction {} bv-u8-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1309 | @deftypefnx Instruction {} bv-s8-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1310 | @deftypefnx Instruction {} bv-u16-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1311 | @deftypefnx Instruction {} bv-s16-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1312 | @deftypefnx Instruction {} bv-u32-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1313 | @deftypefnx Instruction {} bv-s32-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1314 | @deftypefnx Instruction {} bv-u64-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1315 | @deftypefnx Instruction {} bv-s64-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1316 | @deftypefnx Instruction {} bv-f32-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1317 | @deftypefnx Instruction {} bv-f64-set! u8:@var{dst} u8:@var{idx} u8:@var{src} | |
1318 | ||
1319 | Store @var{src} into the bytevector @var{dst} at byte offset @var{idx}. | |
1320 | Multibyte values are written using native endianness. | |
1321 | @end deftypefn |