12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358 |
- @c -*-texinfo-*-
- @c This is part of the GNU Guile Reference Manual.
- @c Copyright (C) 2008,2009,2010,2011
- @c Free Software Foundation, Inc.
- @c See the file guile.texi for copying conditions.
- @node A Virtual Machine for Guile
- @section A Virtual Machine for Guile
- Guile has both an interpreter and a compiler. To a user, the difference
- is transparent---interpreted and compiled procedures can call each other
- as they please.
- The difference is that the compiler creates and interprets bytecode
- for a custom virtual machine, instead of interpreting the
- S-expressions directly. Loading and running compiled code is faster
- than loading and running source code.
- The virtual machine that does the bytecode interpretation is a part of
- Guile itself. This section describes the nature of Guile's virtual
- machine.
- @menu
- * Why a VM?::
- * VM Concepts::
- * Stack Layout::
- * Variables and the VM::
- * VM Programs::
- * Instruction Set::
- @end menu
- @node Why a VM?
- @subsection Why a VM?
- @cindex interpreter
- For a long time, Guile only had an interpreter. Guile's interpreter
- operated directly on the S-expression representation of Scheme source
- code.
- But while the interpreter was highly optimized and hand-tuned, it still
- performs many needless computations during the course of evaluating an
- expression. For example, application of a function to arguments
- needlessly consed up the arguments in a list. Evaluation of an
- expression always had to figure out what the car of the expression is --
- a procedure, a memoized form, or something else. All values have to be
- allocated on the heap. Et cetera.
- The solution to this problem was to compile the higher-level language,
- Scheme, into a lower-level language for which all of the checks and
- dispatching have already been done---the code is instead stripped to
- the bare minimum needed to ``do the job''.
- The question becomes then, what low-level language to choose? There
- are many options. We could compile to native code directly, but that
- poses portability problems for Guile, as it is a highly cross-platform
- project.
- So we want the performance gains that compilation provides, but we
- also want to maintain the portability benefits of a single code path.
- The obvious solution is to compile to a virtual machine that is
- present on all Guile installations.
- The easiest (and most fun) way to depend on a virtual machine is to
- implement the virtual machine within Guile itself. This way the
- virtual machine provides what Scheme needs (tail calls, multiple
- values, @code{call/cc}) and can provide optimized inline instructions
- for Guile (@code{cons}, @code{struct-ref}, etc.).
- So this is what Guile does. The rest of this section describes that VM
- that Guile implements, and the compiled procedures that run on it.
- Before moving on, though, we should note that though we spoke of the
- interpreter in the past tense, Guile still has an interpreter. The
- difference is that before, it was Guile's main evaluator, and so was
- implemented in highly optimized C; now, it is actually implemented in
- Scheme, and compiled down to VM bytecode, just like any other program.
- (There is still a C interpreter around, used to bootstrap the compiler,
- but it is not normally used at runtime.)
- The upside of implementing the interpreter in Scheme is that we preserve
- tail calls and multiple-value handling between interpreted and compiled
- code. The downside is that the interpreter in Guile 2.@var{x} is slower
- than the interpreter in 1.8. We hope the that the compiler's speed makes
- up for the loss!
- Also note that this decision to implement a bytecode compiler does not
- preclude native compilation. We can compile from bytecode to native
- code at runtime, or even do ahead of time compilation. More
- possibilities are discussed in @ref{Extending the Compiler}.
- @node VM Concepts
- @subsection VM Concepts
- Compiled code is run by a virtual machine (VM). Each thread has its own
- VM. When a compiled procedure is run, Guile looks up the virtual machine
- for the current thread and executes the procedure using that VM.
- Guile's virtual machine is a stack machine---that is, it has few
- registers, and the instructions defined in the VM operate by pushing
- and popping values from a stack.
- Stack memory is exclusive to the virtual machine that owns it. In
- addition to their stacks, virtual machines also have access to the
- global memory (modules, global bindings, etc) that is shared among
- other parts of Guile, including other VMs.
- A VM has generic instructions, such as those to reference local
- variables, and instructions designed to support Guile's languages --
- mathematical instructions that support the entire numerical tower, an
- inlined implementation of @code{cons}, etc.
- The registers that a VM has are as follows:
- @itemize
- @item ip - Instruction pointer
- @item sp - Stack pointer
- @item fp - Frame pointer
- @end itemize
- In other architectures, the instruction pointer is sometimes called
- the ``program counter'' (pc). This set of registers is pretty typical
- for stack machines; their exact meanings in the context of Guile's VM
- are described in the next section.
- @c wingo: The following is true, but I don't know in what context to
- @c describe it. A documentation FIXME.
- @c A VM may have one of three engines: reckless, regular, or debugging.
- @c Reckless engine is fastest but dangerous. Regular engine is normally
- @c fail-safe and reasonably fast. Debugging engine is safest and
- @c functional but very slow.
- @c (Actually we have just a regular and a debugging engine; normally
- @c we use the latter, it's almost as fast as the ``regular'' engine.)
- @node Stack Layout
- @subsection Stack Layout
- While not strictly necessary to understand how to work with the VM, it
- is instructive and sometimes entertaining to consider the structure of
- the VM stack.
- Logically speaking, a VM stack is composed of ``frames''. Each frame
- corresponds to the application of one compiled procedure, and contains
- storage space for arguments, local variables, intermediate values, and
- some bookkeeping information (such as what to do after the frame
- computes its value).
- While the compiler is free to do whatever it wants to, as long as the
- semantics of a computation are preserved, in practice every time you
- call a function, a new frame is created. (The notable exception of
- course is the tail call case, @pxref{Tail Calls}.)
- Within a frame, you have the data associated with the function
- application itself, which is of a fixed size, and the stack space for
- intermediate values. Sometimes only the former is referred to as the
- ``frame'', and the latter is the ``stack'', although all pending
- application frames can have some intermediate computations interleaved
- on the stack.
- The structure of the fixed part of an application frame is as follows:
- @example
- Stack
- | ... |
- | Intermed. val. 0 | <- fp + bp->nargs + bp->nlocs = SCM_FRAME_UPPER_ADDRESS (fp)
- +==================+
- | Local variable 1 |
- | Local variable 0 | <- fp + bp->nargs
- | Argument 1 |
- | Argument 0 | <- fp
- | Program | <- fp - 1
- +------------------+
- | Return address |
- | MV return address|
- | Dynamic link | <- fp - 4 = SCM_FRAME_DATA_ADDRESS (fp) = SCM_FRAME_LOWER_ADDRESS (fp)
- +==================+
- | |
- @end example
- In the above drawing, the stack grows upward. The intermediate values
- stored in the application of this frame are stored above
- @code{SCM_FRAME_UPPER_ADDRESS (fp)}. @code{bp} refers to the
- @code{struct scm_objcode} data associated with the program at
- @code{fp - 1}. @code{nargs} and @code{nlocs} are properties of the
- compiled procedure, which will be discussed later.
- The individual fields of the frame are as follows:
- @table @asis
- @item Return address
- The @code{ip} that was in effect before this program was applied. When
- we return from this activation frame, we will jump back to this
- @code{ip}.
- @item MV return address
- The @code{ip} to return to if this application returns multiple
- values. For continuations that only accept one value, this value will
- be @code{NULL}; for others, it will be an @code{ip} that points to a
- multiple-value return address in the calling code. That code will
- expect the top value on the stack to be an integer---the number of
- values being returned---and that below that integer there are the
- values being returned.
- @item Dynamic link
- This is the @code{fp} in effect before this program was applied. In
- effect, this and the return address are the registers that are always
- ``saved''. The dynamic link links the current frame to the previous
- frame; computing a stack trace involves traversing these frames.
- @item Local variable @var{n}
- Lambda-local variables that are all allocated as part of the frame.
- This makes access to variables very cheap.
- @item Argument @var{n}
- The calling convention of the VM requires arguments of a function
- application to be pushed on the stack, and here they are. References
- to arguments dispatch to these locations on the stack.
- @item Program
- This is the program being applied. For more information on how
- programs are implemented, @xref{VM Programs}.
- @end table
- @node Variables and the VM
- @subsection Variables and the VM
- Consider the following Scheme code as an example:
- @example
- (define (foo a)
- (lambda (b) (list foo a b)))
- @end example
- Within the lambda expression, @code{foo} is a top-level variable, @code{a} is a
- lexically captured variable, and @code{b} is a local variable.
- Another way to refer to @code{a} and @code{b} is to say that @code{a}
- is a ``free'' variable, since it is not defined within the lambda, and
- @code{b} is a ``bound'' variable. These are the terms used in the
- @dfn{lambda calculus}, a mathematical notation for describing
- functions. The lambda calculus is useful because it allows one to
- prove statements about functions. It is especially good at describing
- scope relations, and it is for that reason that we mention it here.
- Guile allocates all variables on the stack. When a lexically enclosed
- procedure with free variables---a @dfn{closure}---is created, it copies
- those variables into its free variable vector. References to free
- variables are then redirected through the free variable vector.
- If a variable is ever @code{set!}, however, it will need to be
- heap-allocated instead of stack-allocated, so that different closures
- that capture the same variable can see the same value. Also, this
- allows continuations to capture a reference to the variable, instead
- of to its value at one point in time. For these reasons, @code{set!}
- variables are allocated in ``boxes''---actually, in variable cells.
- @xref{Variables}, for more information. References to @code{set!}
- variables are indirected through the boxes.
- Thus perhaps counterintuitively, what would seem ``closer to the
- metal'', viz @code{set!}, actually forces an extra memory allocation
- and indirection.
- Going back to our example, @code{b} may be allocated on the stack, as
- it is never mutated.
- @code{a} may also be allocated on the stack, as it too is never
- mutated. Within the enclosed lambda, its value will be copied into
- (and referenced from) the free variables vector.
- @code{foo} is a top-level variable, because @code{foo} is not
- lexically bound in this example.
- @node VM Programs
- @subsection Compiled Procedures are VM Programs
- By default, when you enter in expressions at Guile's REPL, they are
- first compiled to VM object code, then that VM object code is executed
- to produce a value. If the expression evaluates to a procedure, the
- result of this process is a compiled procedure.
- A compiled procedure is a compound object, consisting of its bytecode,
- a reference to any captured lexical variables, an object array, and
- some metadata such as the procedure's arity, name, and documentation.
- You can pick apart these pieces with the accessors in @code{(system vm
- program)}. @xref{Compiled Procedures}, for a full API reference.
- @cindex object table
- @cindex object array
- The object array of a compiled procedure, also known as the
- @dfn{object table}, holds all Scheme objects whose values are known
- not to change across invocations of the procedure: constant strings,
- symbols, etc. The object table of a program is initialized right
- before a program is loaded with @code{load-program}.
- @xref{Loading Instructions}, for more information.
- Variable objects are one such type of constant object: when a global
- binding is defined, a variable object is associated to it and that
- object will remain constant over time, even if the value bound to it
- changes. Therefore, toplevel bindings only need to be looked up once.
- Thereafter, references to the corresponding toplevel variables from
- within the program are then performed via the @code{toplevel-ref}
- instruction, which uses the object vector, and are almost as fast as
- local variable references.
- We can see how these concepts tie together by disassembling the
- @code{foo} function we defined earlier to see what is going on:
- @smallexample
- scheme@@(guile-user)> (define (foo a) (lambda (b) (list foo a b)))
- scheme@@(guile-user)> ,x foo
- 0 (assert-nargs-ee/locals 1)
- 2 (object-ref 1) ;; #<procedure 8ebec20 at <current input>:0:17 (b)>
- 4 (local-ref 0) ;; `a'
- 6 (make-closure 0 1)
- 9 (return)
- ----------------------------------------
- Disassembly of #<procedure 8ebec20 at <current input>:0:17 (b)>:
- 0 (assert-nargs-ee/locals 1)
- 2 (toplevel-ref 1) ;; `foo'
- 4 (free-ref 0) ;; (closure variable)
- 6 (local-ref 0) ;; `b'
- 8 (list 0 3) ;; 3 elements at (unknown file):0:29
- 11 (return)
- @end smallexample
- First there's some prelude, where @code{foo} checks that it was called with only
- 1 argument. Then at @code{ip} 2, we load up the compiled lambda. @code{Ip} 4
- loads up `a', so that it can be captured into a closure by at @code{ip}
- 6---binding code (from the compiled lambda) with data (the free-variable
- vector). Finally we return the closure.
- The second stanza disassembles the compiled lambda. After the prelude, we note
- that toplevel variables are resolved relative to the module that was current
- when the procedure was created. This lookup occurs lazily, at the first time the
- variable is actually referenced, and the location of the lookup is cached so
- that future references are very cheap. @xref{Top-Level Environment Instructions},
- for more details.
- Then we see a reference to a free variable, corresponding to @code{a}. The
- disassembler doesn't have enough information to give a name to that variable, so
- it just marks it as being a ``closure variable''. Finally we see the reference
- to @code{b}, then the @code{list} opcode, an inline implementation of the
- @code{list} scheme routine.
- @node Instruction Set
- @subsection Instruction Set
- There are about 180 instructions in Guile's virtual machine. These
- instructions represent atomic units of a program's execution. Ideally,
- they perform one task without conditional branches, then dispatch to
- the next instruction in the stream.
- Instructions themselves are one byte long. Some instructions take
- parameters, which follow the instruction byte in the instruction
- stream.
- Sometimes the compiler can figure out that it is compiling a special
- case that can be run more efficiently. So, for example, while Guile
- offers a generic test-and-branch instruction, it also offers specific
- instructions for special cases, so that the following cases all have
- their own test-and-branch instructions:
- @example
- (if pred then else)
- (if (not pred) then else)
- (if (null? l) then else)
- (if (not (null? l)) then else)
- @end example
- In addition, some Scheme primitives have their own inline
- implementations, e.g.@: @code{cons}, and @code{list}, as we saw in the
- previous section.
- So Guile's instruction set is a @emph{complete} instruction set, in
- that it provides the instructions that are suited to the problem, and
- is not concerned with making a minimal, orthogonal set of
- instructions. More instructions may be added over time.
- @menu
- * Lexical Environment Instructions::
- * Top-Level Environment Instructions::
- * Procedure Call and Return Instructions::
- * Function Prologue Instructions::
- * Trampoline Instructions::
- * Branch Instructions::
- * Data Constructor Instructions::
- * Loading Instructions::
- * Dynamic Environment Instructions::
- * Miscellaneous Instructions::
- * Inlined Scheme Instructions::
- * Inlined Mathematical Instructions::
- * Inlined Bytevector Instructions::
- @end menu
- @node Lexical Environment Instructions
- @subsubsection Lexical Environment Instructions
- These instructions access and mutate the lexical environment of a
- compiled procedure---its free and bound variables.
- Some of these instructions have @code{long-} variants, the difference
- being that they take 16-bit arguments, encoded in big-endianness,
- instead of the normal 8-bit range.
- @xref{Stack Layout}, for more information on the format of stack frames.
- @deffn Instruction local-ref index
- @deffnx Instruction long-local-ref index
- Push onto the stack the value of the local variable located at
- @var{index} within the current stack frame.
- Note that arguments and local variables are all in one block. Thus the
- first argument, if any, is at index 0, and local bindings follow the
- arguments.
- @end deffn
- @deffn Instruction local-set index
- @deffnx Instruction long-local-set index
- Pop the Scheme object located on top of the stack and make it the new
- value of the local variable located at @var{index} within the current
- stack frame.
- @end deffn
- @deffn Instruction box index
- Pop a value off the stack, and set the @var{index}nth local variable
- to a box containing that value. A shortcut for @code{make-variable}
- then @code{local-set}, used when binding boxed variables.
- @end deffn
- @deffn Instruction empty-box index
- Set the @var{indext}h local variable to a box containing a variable
- whose value is unbound. Used when compiling some @code{letrec}
- expressions.
- @end deffn
- @deffn Instruction local-boxed-ref index
- @deffnx Instruction local-boxed-ref index
- Get or set the value of the variable located at @var{index} within the
- current stack frame. A shortcut for @code{local-ref} then
- @code{variable-ref} or @code{variable-set}, respectively.
- @end deffn
- @deffn Instruction free-ref index
- Push the value of the captured variable located at position
- @var{index} within the program's vector of captured variables.
- @end deffn
- @deffn Instruction free-boxed-ref index
- @deffnx Instruction free-boxed-set index
- Get or set a boxed free variable. A shortcut for @code{free-ref} then
- @code{variable-ref} or @code{variable-set}, respectively.
- Note that there is no @code{free-set} instruction, as variables that are
- @code{set!} must be boxed.
- @end deffn
- @deffn Instruction make-closure num-free-vars
- Pop @var{num-free-vars} values and a program object off the stack in
- that order, and push a new program object closing over the given free
- variables. @var{num-free-vars} is encoded as a two-byte big-endian
- value.
- The free variables are stored in an array, inline to the new program
- object, in the order that they were on the stack (not the order they are
- popped off). The new closure shares state with the original program. At
- the time of this writing, the space overhead of closures is 3 words,
- plus one word for each free variable.
- @end deffn
- @deffn Instruction fix-closure index
- Fix up the free variables array of the closure stored in the
- @var{index}th local variable. @var{index} is a two-byte big-endian
- integer.
- This instruction will pop as many values from the stack as are in the
- corresponding closure's free variables array. The topmost value on the
- stack will be stored as the closure's last free variable, with other
- values filling in free variable slots in order.
- @code{fix-closure} is part of a hack for allocating mutually recursive
- procedures. The hack is to store the procedures in their corresponding
- local variable slots, with space already allocated for free variables.
- Then once they are all in place, this instruction fixes up their
- procedures' free variable bindings in place. This allows most
- @code{letrec}-bound procedures to be allocated unboxed on the stack.
- @end deffn
- @deffn Instruction local-bound? index
- @deffnx Instruction long-local-bound? index
- Push @code{#t} on the stack if the @code{index}th local variable has
- been assigned, or @code{#f} otherwise. Mostly useful for handling
- optional arguments in procedure prologues.
- @end deffn
- @node Top-Level Environment Instructions
- @subsubsection Top-Level Environment Instructions
- These instructions access values in the top-level environment: bindings
- that were not lexically apparent at the time that the code in question
- was compiled.
- The location in which a toplevel binding is stored can be looked up once
- and cached for later. The binding itself may change over time, but its
- location will stay constant.
- Currently only toplevel references within procedures are cached, as only
- procedures have a place to cache them, in their object tables.
- @deffn Instruction toplevel-ref index
- @deffnx Instruction long-toplevel-ref index
- Push the value of the toplevel binding whose location is stored in at
- position @var{index} in the current procedure's object table. The
- @code{long-} variant encodes the index over two bytes.
- Initially, a cell in a procedure's object table that is used by
- @code{toplevel-ref} is initialized to one of two forms. The normal case
- is that the cell holds a symbol, whose binding will be looked up
- relative to the module that was current when the current program was
- created.
- Alternately, the lookup may be performed relative to a particular
- module, determined at compile-time (e.g.@: via @code{@@} or
- @code{@@@@}). In that case, the cell in the object table holds a list:
- @code{(@var{modname} @var{sym} @var{public?})}. The symbol @var{sym}
- will be looked up in the module named @var{modname} (a list of
- symbols). The lookup will be performed against the module's public
- interface, unless @var{public?} is @code{#f}, which it is for example
- when compiling @code{@@@@}.
- In any case, if the symbol is unbound, an error is signalled.
- Otherwise the initial form is replaced with the looked-up variable, an
- in-place mutation of the object table. This mechanism provides for
- lazy variable resolution, and an important cached fast-path once the
- variable has been successfully resolved.
- This instruction pushes the value of the variable onto the stack.
- @end deffn
- @deffn Instruction toplevel-set index
- @deffnx Instruction long-toplevel-set index
- Pop a value off the stack, and set it as the value of the toplevel
- variable stored at @var{index} in the object table. If the variable
- has not yet been looked up, we do the lookup as in
- @code{toplevel-ref}.
- @end deffn
- @deffn Instruction define
- Pop a symbol and a value from the stack, in that order. Look up its
- binding in the current toplevel environment, creating the binding if
- necessary. Set the variable to the value.
- @end deffn
- @deffn Instruction link-now
- Pop a value, @var{x}, from the stack. Look up the binding for @var{x},
- according to the rules for @code{toplevel-ref}, and push that variable
- on the stack. If the lookup fails, an error will be signalled.
- This instruction is mostly used when loading programs, because it can
- do toplevel variable lookups without an object table.
- @end deffn
- @deffn Instruction variable-ref
- Dereference the variable object which is on top of the stack and
- replace it by the value of the variable it represents.
- @end deffn
- @deffn Instruction variable-set
- Pop off two objects from the stack, a variable and a value, and set
- the variable to the value.
- @end deffn
- @deffn Instruction variable-bound?
- Pop off the variable object from top of the stack and push @code{#t} if
- it is bound, or @code{#f} otherwise. Mostly useful in procedure
- prologues for defining default values for boxed optional variables.
- @end deffn
- @deffn Instruction make-variable
- Replace the top object on the stack with a variable containing it.
- Used in some circumstances when compiling @code{letrec} expressions.
- @end deffn
- @node Procedure Call and Return Instructions
- @subsubsection Procedure Call and Return Instructions
- @c something about the calling convention here?
- @deffn Instruction new-frame
- Push a new frame on the stack, reserving space for the dynamic link,
- return address, and the multiple-values return address. The frame
- pointer is not yet updated, because the frame is not yet active -- it
- has to be patched by a @code{call} instruction to get the return
- address.
- @end deffn
- @deffn Instruction call nargs
- Call the procedure located at @code{sp[-nargs]} with the @var{nargs}
- arguments located from @code{sp[-nargs + 1]} to @code{sp[0]}.
- This instruction requires that a new frame be pushed on the stack before
- the procedure, via @code{new-frame}. @xref{Stack Layout}, for more
- information. It patches up that frame with the current @code{ip} as the
- return address, then dispatches to the first instruction in the called
- procedure, relying on the called procedure to return one value to the
- newly-created continuation. Because the new frame pointer will point to
- @code{sp[-nargs + 1]}, the arguments don't have to be shuffled around --
- they are already in place.
- @end deffn
- @deffn Instruction tail-call nargs
- Transfer control to the procedure located at @code{sp[-nargs]} with the
- @var{nargs} arguments located from @code{sp[-nargs + 1]} to
- @code{sp[0]}.
- Unlike @code{call}, which requires a new frame to be pushed onto the
- stack, @code{tail-call} simply shuffles down the procedure and arguments
- to the current stack frame. This instruction implements tail calls as
- required by RnRS.
- @end deffn
- @deffn Instruction apply nargs
- @deffnx Instruction tail-apply nargs
- Like @code{call} and @code{tail-call}, except that the top item on the
- stack must be a list. The elements of that list are then pushed on the
- stack and treated as additional arguments, replacing the list itself,
- then the procedure is invoked as usual.
- @end deffn
- @deffn Instruction call/nargs
- @deffnx Instruction tail-call/nargs
- These are like @code{call} and @code{tail-call}, except they take the
- number of arguments from the stack instead of the instruction stream.
- These instructions are used in the implementation of multiple value
- returns, where the actual number of values is pushed on the stack.
- @end deffn
- @deffn Instruction mv-call nargs offset
- Like @code{call}, except that a multiple-value continuation is created
- in addition to a single-value continuation.
- The offset (a three-byte value) is an offset within the instruction
- stream; the multiple-value return address in the new frame (@pxref{Stack
- Layout}) will be set to the normal return address plus this offset.
- Instructions at that offset will expect the top value of the stack to be
- the number of values, and below that values themselves, pushed
- separately.
- @end deffn
- @deffn Instruction return
- Free the program's frame, returning the top value from the stack to
- the current continuation. (The stack should have exactly one value on
- it.)
- Specifically, the @code{sp} is decremented to one below the current
- @code{fp}, the @code{ip} is reset to the current return address, the
- @code{fp} is reset to the value of the current dynamic link, and then
- the returned value is pushed on the stack.
- @end deffn
- @deffn Instruction return/values nvalues
- @deffnx Instruction return/nvalues
- Return the top @var{nvalues} to the current continuation. In the case of
- @code{return/nvalues}, @var{nvalues} itself is first popped from the top
- of the stack.
- If the current continuation is a multiple-value continuation,
- @code{return/values} pushes the number of values on the stack, then
- returns as in @code{return}, but to the multiple-value return address.
- Otherwise if the current continuation accepts only one value, i.e.@: the
- multiple-value return address is @code{NULL}, then we assume the user
- only wants one value, and we give them the first one. If there are no
- values, an error is signaled.
- @end deffn
- @deffn Instruction return/values* nvalues
- Like a combination of @code{apply} and @code{return/values}, in which
- the top value on the stack is interpreted as a list of additional
- values. This is an optimization for the common @code{(apply values
- ...)} case.
- @end deffn
- @deffn Instruction truncate-values nbinds nrest
- Used in multiple-value continuations, this instruction takes the
- values that are on the stack (including the number-of-values marker)
- and truncates them for a binding construct.
- For example, a call to @code{(receive (x y . z) (foo) ...)} would,
- logically speaking, pop off the values returned from @code{(foo)} and
- push them as three values, corresponding to @code{x}, @code{y}, and
- @code{z}. In that case, @var{nbinds} would be 3, and @var{nrest} would
- be 1 (to indicate that one of the bindings was a rest argument).
- Signals an error if there is an insufficient number of values.
- @end deffn
- @deffn Instruction call/cc
- @deffnx Instruction tail-call/cc
- Capture the current continuation, and then call (or tail-call) the
- procedure on the top of the stack, with the continuation as the
- argument.
- @code{call/cc} does not require a @code{new-frame} to be pushed on the
- stack, as @code{call} does, because it needs to capture the stack
- before the frame is pushed.
- Both the VM continuation and the C continuation are captured.
- @end deffn
- @node Function Prologue Instructions
- @subsubsection Function Prologue Instructions
- A function call in Guile is very cheap: the VM simply hands control to
- the procedure. The procedure itself is responsible for asserting that it
- has been passed an appropriate number of arguments. This strategy allows
- arbitrarily complex argument parsing idioms to be developed, without
- harming the common case.
- For example, only calls to keyword-argument procedures ``pay'' for the
- cost of parsing keyword arguments. (At the time of this writing, calling
- procedures with keyword arguments is typically two to four times as
- costly as calling procedures with a fixed set of arguments.)
- @deffn Instruction assert-nargs-ee n
- @deffnx Instruction assert-nargs-ge n
- Assert that the current procedure has been passed exactly @var{n}
- arguments, for the @code{-ee} case, or @var{n} or more arguments, for
- the @code{-ge} case. @var{n} is encoded over two bytes.
- The number of arguments is determined by subtracting the frame pointer
- from the stack pointer (@code{sp - (fp -1)}). @xref{Stack Layout}, for
- more details on stack frames.
- @end deffn
- @deffn Instruction br-if-nargs-ne n offset
- @deffnx Instruction br-if-nargs-gt n offset
- @deffnx Instruction br-if-nargs-lt n offset
- Jump to @var{offset} if the number of arguments is not equal to, greater
- than, or less than @var{n}. @var{n} is encoded over two bytes, and
- @var{offset} has the normal three-byte encoding.
- These instructions are used to implement multiple arities, as in
- @code{case-lambda}. @xref{Case-lambda}, for more information.
- @end deffn
- @deffn Instruction bind-optionals n
- If the procedure has been called with fewer than @var{n} arguments, fill
- in the remaining arguments with an unbound value (@code{SCM_UNDEFINED}).
- @var{n} is encoded over two bytes.
- The optionals can be later initialized conditionally via the
- @code{local-bound?} instruction.
- @end deffn
- @deffn Instruction push-rest n
- Pop off excess arguments (more than @var{n}), collecting them into a
- list, and push that list. Used to bind a rest argument, if the procedure
- has no keyword arguments. Procedures with keyword arguments use
- @code{bind-rest} instead.
- @end deffn
- @deffn Instruction bind-rest n idx
- Pop off excess arguments (more than @var{n}), collecting them into a
- list. The list is then assigned to the @var{idx}th local variable.
- @end deffn
- @deffn Instruction bind-optionals/shuffle nreq nreq-and-opt ntotal
- Shuffle keyword arguments to the top of the stack, filling in the holes
- with @code{SCM_UNDEFINED}. Each argument is encoded over two bytes.
- This instruction is used by procedures with keyword arguments.
- @var{nreq} is the number of required arguments to the procedure, and
- @var{nreq-and-opt} is the total number of positional arguments (required
- plus optional). @code{bind-optionals/shuffle} will scan the stack from
- the @var{nreq}th argument up to the @var{nreq-and-opt}th, and start
- shuffling when it sees the first keyword argument or runs out of
- positional arguments.
- Shuffling simply moves the keyword arguments past the total number of
- arguments, @var{ntotal}, which includes keyword and rest arguments. The
- free slots created by the shuffle are filled in with
- @code{SCM_UNDEFINED}, so they may be conditionally initialized later in
- the function's prologue.
- @end deffn
- @deffn Instruction bind-kwargs idx ntotal flags
- Parse keyword arguments, assigning their values to the corresponding
- local variables. The keyword arguments should already have been shuffled
- above the @var{ntotal}th stack slot by @code{bind-optionals/shuffle}.
- The parsing is driven by a keyword arguments association list, looked up
- from the @var{idx}th element of the procedures object array. The alist
- is a list of pairs of the form @code{(@var{kw} . @var{index})}, mapping
- keyword arguments to their local variable indices.
- There are two bitflags that affect the parser, @code{allow-other-keys?}
- (@code{0x1}) and @code{rest?} (@code{0x2}). Unless
- @code{allow-other-keys?} is set, the parser will signal an error if an
- unknown key is found. If @code{rest?} is set, errors parsing the
- keyword arguments will be ignored, as a later @code{bind-rest}
- instruction will collect all of the tail arguments, including the
- keywords, into a list. Otherwise if the keyword arguments are invalid,
- an error is signalled.
- @var{idx} and @var{ntotal} are encoded over two bytes each, and
- @var{flags} is encoded over one byte.
- @end deffn
- @deffn Instruction reserve-locals n
- Resets the stack pointer to have space for @var{n} local variables,
- including the arguments. If this operation increments the stack pointer,
- as in a push, the new slots are filled with @code{SCM_UNBOUND}. If this
- operation decrements the stack pointer, any excess values are dropped.
- @code{reserve-locals} is typically used after argument parsing to
- reserve space for local variables.
- @end deffn
- @deffn Instruction assert-nargs-ee/locals n
- @deffnx Instruction assert-nargs-ge/locals n
- A combination of @code{assert-nargs-ee} and @code{reserve-locals}. The
- number of arguments is encoded in the lower three bits of @var{n}, a
- one-byte value. The number of additional local variables is take from
- the upper 5 bits of @var{n}.
- @end deffn
- @node Trampoline Instructions
- @subsubsection Trampoline Instructions
- Though most applicable objects in Guile are procedures implemented
- in bytecode, not all are. There are primitives, continuations, and other
- procedure-like objects that have their own calling convention. Instead
- of adding special cases to the @code{call} instruction, Guile wraps
- these other applicable objects in VM trampoline procedures, then
- provides special support for these objects in bytecode.
- Trampoline procedures are typically generated by Guile at runtime, for
- example in response to a call to @code{scm_c_make_gsubr}. As such, a
- compiler probably shouldn't emit code with these instructions. However,
- it's still interesting to know how these things work, so we document
- these trampoline instructions here.
- @deffn Instruction subr-call nargs
- Pop off a foreign pointer (which should have been pushed on by the
- trampoline), and call it directly, with the @var{nargs} arguments from
- the stack. Return the resulting value or values to the calling
- procedure.
- @end deffn
- @deffn Instruction foreign-call nargs
- Pop off an internal foreign object (which should have been pushed on by
- the trampoline), and call that foreign function with the @var{nargs}
- arguments from the stack. Return the resulting value to the calling
- procedure.
- @end deffn
- @deffn Instruction smob-call nargs
- Pop off the smob object from the stack (which should have been pushed on
- by the trampoline), and call its descriptor's @code{apply} function with
- the @var{nargs} arguments from the stack. Return the resulting value or
- values to the calling procedure.
- @end deffn
- @deffn Instruction continuation-call
- Pop off an internal continuation object (which should have been pushed
- on by the trampoline), and reinstate that continuation. All of the
- procedure's arguments are passed to the continuation. Does not return.
- @end deffn
- @deffn Instruction partial-cont-call
- Pop off two objects from the stack: the dynamic winds associated with
- the partial continuation, and the VM continuation object. Unroll the
- continuation onto the stack, rewinding the dynamic environment and
- overwriting the current frame, and pass all arguments to the
- continuation. Control flow proceeds where the continuation was captured.
- @end deffn
- @node Branch Instructions
- @subsubsection Branch Instructions
- All the conditional branch instructions described below work in the
- same way:
- @itemize
- @item They pop off Scheme object(s) located on the stack for use in the
- branch condition
- @item If the condition is true, then the instruction pointer is
- increased by the offset passed as an argument to the branch
- instruction;
- @item Program execution proceeds with the next instruction (that is,
- the one to which the instruction pointer points).
- @end itemize
- Note that the offset passed to the instruction is encoded as three 8-bit
- integers, in big-endian order, effectively giving Guile a 24-bit
- relative address space.
- @deffn Instruction br offset
- Jump to @var{offset}. No values are popped.
- @end deffn
- @deffn Instruction br-if offset
- Jump to @var{offset} if the object on the stack is not false.
- @end deffn
- @deffn Instruction br-if-not offset
- Jump to @var{offset} if the object on the stack is false.
- @end deffn
- @deffn Instruction br-if-eq offset
- Jump to @var{offset} if the two objects located on the stack are
- equal in the sense of @var{eq?}. Note that, for this instruction, the
- stack pointer is decremented by two Scheme objects instead of only
- one.
- @end deffn
- @deffn Instruction br-if-not-eq offset
- Same as @var{br-if-eq} for non-@code{eq?} objects.
- @end deffn
- @deffn Instruction br-if-null offset
- Jump to @var{offset} if the object on the stack is @code{'()}.
- @end deffn
- @deffn Instruction br-if-not-null offset
- Jump to @var{offset} if the object on the stack is not @code{'()}.
- @end deffn
- @node Data Constructor Instructions
- @subsubsection Data Constructor Instructions
- These instructions push simple immediate values onto the stack,
- or construct compound data structures from values on the stack.
- @deffn Instruction make-int8 value
- Push @var{value}, an 8-bit integer, onto the stack.
- @end deffn
- @deffn Instruction make-int8:0
- Push the immediate value @code{0} onto the stack.
- @end deffn
- @deffn Instruction make-int8:1
- Push the immediate value @code{1} onto the stack.
- @end deffn
- @deffn Instruction make-int16 value
- Push @var{value}, a 16-bit integer, onto the stack.
- @end deffn
- @deffn Instruction make-uint64 value
- Push @var{value}, an unsigned 64-bit integer, onto the stack. The
- value is encoded in 8 bytes, most significant byte first (big-endian).
- @end deffn
- @deffn Instruction make-int64 value
- Push @var{value}, a signed 64-bit integer, onto the stack. The value
- is encoded in 8 bytes, most significant byte first (big-endian), in
- twos-complement arithmetic.
- @end deffn
- @deffn Instruction make-false
- Push @code{#f} onto the stack.
- @end deffn
- @deffn Instruction make-true
- Push @code{#t} onto the stack.
- @end deffn
- @deffn Instruction make-nil
- Push @code{#nil} onto the stack.
- @end deffn
- @deffn Instruction make-eol
- Push @code{'()} onto the stack.
- @end deffn
- @deffn Instruction make-char8 value
- Push @var{value}, an 8-bit character, onto the stack.
- @end deffn
- @deffn Instruction make-char32 value
- Push @var{value}, an 32-bit character, onto the stack. The value is
- encoded in big-endian order.
- @end deffn
- @deffn Instruction make-symbol
- Pops a string off the stack, and pushes a symbol.
- @end deffn
- @deffn Instruction make-keyword value
- Pops a symbol off the stack, and pushes a keyword.
- @end deffn
- @deffn Instruction list n
- Pops off the top @var{n} values off of the stack, consing them up into
- a list, then pushes that list on the stack. What was the topmost value
- will be the last element in the list. @var{n} is a two-byte value,
- most significant byte first.
- @end deffn
- @deffn Instruction vector n
- Create and fill a vector with the top @var{n} values from the stack,
- popping off those values and pushing on the resulting vector. @var{n}
- is a two-byte value, like in @code{vector}.
- @end deffn
- @deffn Instruction make-struct n
- Make a new struct from the top @var{n} values on the stack. The values
- are popped, and the new struct is pushed.
- The deepest value is used as the vtable for the struct, and the rest are
- used in order as the field initializers. Tail arrays are not supported
- by this instruction.
- @end deffn
- @deffn Instruction make-array n
- Pop an array shape from the stack, then pop the remaining @var{n}
- values, pushing a new array. @var{n} is encoded over three bytes.
- The array shape should be appropriate to store @var{n} values.
- @xref{Array Procedures}, for more information on array shapes.
- @end deffn
- Many of these data structures are constant, never changing over the
- course of the different invocations of the procedure. In that case it is
- often advantageous to make them once when the procedure is created, and
- just reference them from the object table thereafter. @xref{Variables
- and the VM}, for more information on the object table.
- @deffn Instruction object-ref n
- @deffnx Instruction long-object-ref n
- Push @var{n}th value from the current program's object vector. The
- ``long'' variant has a 16-bit index instead of an 8-bit index.
- @end deffn
- @node Loading Instructions
- @subsubsection Loading Instructions
- In addition to VM instructions, an instruction stream may contain
- variable-length data embedded within it. This data is always preceded
- by special loading instructions, which interpret the data and advance
- the instruction pointer to the next VM instruction.
- All of these loading instructions have a @code{length} parameter,
- indicating the size of the embedded data, in bytes. The length itself
- is encoded in 3 bytes.
- @deffn Instruction load-number length
- Load an arbitrary number from the instruction stream. The number is
- embedded in the stream as a string.
- @end deffn
- @deffn Instruction load-string length
- Load a string from the instruction stream. The string is assumed to be
- encoded in the ``latin1'' locale.
- @end deffn
- @deffn Instruction load-wide-string length
- Load a UTF-32 string from the instruction stream. @var{length} is the
- length in bytes, not in codepoints.
- @end deffn
- @deffn Instruction load-symbol length
- Load a symbol from the instruction stream. The symbol is assumed to be
- encoded in the ``latin1'' locale. Symbols backed by wide strings may
- be loaded via @code{load-wide-string} then @code{make-symbol}.
- @end deffn
- @deffn Instruction load-array length
- Load a uniform array from the instruction stream. The shape and type
- of the array are popped off the stack, in that order.
- @end deffn
- @deffn Instruction load-program
- Load bytecode from the instruction stream, and push a compiled
- procedure.
- This instruction pops one value from the stack: the program's object
- table, as a vector, or @code{#f} in the case that the program has no
- object table. A program that does not reference toplevel bindings and
- does not use @code{object-ref} does not need an object table.
- This instruction is unlike the rest of the loading instructions,
- because instead of parsing its data, it directly maps the instruction
- stream onto a C structure, @code{struct scm_objcode}. @xref{Bytecode
- and Objcode}, for more information.
- The resulting compiled procedure will not have any free variables
- captured, so it may be loaded only once but used many times to create
- closures.
- @end deffn
- @node Dynamic Environment Instructions
- @subsubsection Dynamic Environment Instructions
- Guile's virtual machine has low-level support for @code{dynamic-wind},
- dynamic binding, and composable prompts and aborts.
- @deffn Instruction wind
- Pop an unwind thunk and a wind thunk from the stack, in that order, and
- push them onto the ``dynamic stack''. The unwind thunk will be called on
- nonlocal exits, and the wind thunk on reentries. Used to implement
- @code{dynamic-wind}.
- Note that neither thunk is actually called; the compiler should emit
- calls to wind and unwind for the normal dynamic-wind control flow.
- @xref{Dynamic Wind}.
- @end deffn
- @deffn Instruction unwind
- Pop off the top entry from the ``dynamic stack'', for example, a
- wind/unwind thunk pair. @code{unwind} instructions should be properly
- paired with their winding instructions, like @code{wind}.
- @end deffn
- @deffn Instruction wind-fluids n
- Pop off @var{n} values and @var{n} fluids from the stack, in that order.
- Set the fluids to the values by creating a with-fluids object and
- pushing that object on the dynamic stack. @xref{Fluids and Dynamic
- States}.
- @end deffn
- @deffn Instruction unwind-fluids
- Pop a with-fluids object from the dynamic stack, and swap the current
- values of its fluids with the saved values of its fluids. In this way,
- the dynamic environment is left as it was before the corresponding
- @code{wind-fluids} instruction was processed.
- @end deffn
- @deffn Instruction fluid-ref
- Pop a fluid from the stack, and push its current value.
- @end deffn
- @deffn Instruction fluid-set
- Pop a value and a fluid from the stack, in that order, and set the fluid
- to the value.
- @end deffn
- @deffn Instruction prompt escape-only? offset
- Establish a dynamic prompt. @xref{Prompts}, for more information on
- prompts.
- The prompt will be pushed on the dynamic stack. The normal control flow
- should ensure that the prompt is popped off at the end, via
- @code{unwind}.
- If an abort is made to this prompt, control will jump to @var{offset}, a
- three-byte relative address. The continuation and all arguments to the
- abort will be pushed on the stack, along with the total number of
- arguments (including the continuation. If control returns to the
- handler, the prompt is already popped off by the abort mechanism.
- (Guile's @code{prompt} implements Felleisen's @dfn{--F--} operator.)
- If @var{escape-only?} is nonzero, the prompt will be marked as
- escape-only, which allows an abort to this prompt to avoid reifying the
- continuation.
- @end deffn
- @deffn Instruction abort n
- Abort to a dynamic prompt.
- This instruction pops one tail argument list, @var{n} arguments, and a
- prompt tag from the stack. The dynamic environment is then searched for
- a prompt having the given tag. If none is found, an error is signalled.
- Otherwise all arguments are passed to the prompt's handler, along with
- the captured continuation, if necessary.
- If the prompt's handler can be proven to not reference the captured
- continuation, no continuation is allocated. This decision happens
- dynamically, at run-time; the general case is that the continuation may
- be captured, and thus resumed. A reinstated continuation will have its
- arguments pushed on the stack, along with the number of arguments, as in
- the multiple-value return convention. Therefore an @code{abort}
- instruction should be followed by code ready to handle the equivalent of
- a multiply-valued return.
- @end deffn
- @node Miscellaneous Instructions
- @subsubsection Miscellaneous Instructions
- @deffn Instruction nop
- Does nothing! Used for padding other instructions to certain
- alignments.
- @end deffn
- @deffn Instruction halt
- Exits the VM, returning a SCM value. Normally, this instruction is
- only part of the ``bootstrap program'', a program run when a virtual
- machine is first entered; compiled Scheme procedures will not contain
- this instruction.
- If multiple values have been returned, the SCM value will be a
- multiple-values object (@pxref{Multiple Values}).
- @end deffn
- @deffn Instruction break
- Does nothing, but invokes the break hook.
- @end deffn
- @deffn Instruction drop
- Pops off the top value from the stack, throwing it away.
- @end deffn
- @deffn Instruction dup
- Re-pushes the top value onto the stack.
- @end deffn
- @deffn Instruction void
- Pushes ``the unspecified value'' onto the stack.
- @end deffn
- @node Inlined Scheme Instructions
- @subsubsection Inlined Scheme Instructions
- The Scheme compiler can recognize the application of standard Scheme
- procedures. It tries to inline these small operations to avoid the
- overhead of creating new stack frames.
- Since most of these operations are historically implemented as C
- primitives, not inlining them would entail constantly calling out from
- the VM to the interpreter, which has some costs---registers must be
- saved, the interpreter has to dispatch, called procedures have to do
- much type checking, etc. It's much more efficient to inline these
- operations in the virtual machine itself.
- All of these instructions pop their arguments from the stack and push
- their results, and take no parameters from the instruction stream.
- Thus, unlike in the previous sections, these instruction definitions
- show stack parameters instead of parameters from the instruction
- stream.
- @deffn Instruction not x
- @deffnx Instruction not-not x
- @deffnx Instruction eq? x y
- @deffnx Instruction not-eq? x y
- @deffnx Instruction null?
- @deffnx Instruction not-null?
- @deffnx Instruction eqv? x y
- @deffnx Instruction equal? x y
- @deffnx Instruction pair? x y
- @deffnx Instruction list? x
- @deffnx Instruction set-car! pair x
- @deffnx Instruction set-cdr! pair x
- @deffnx Instruction cons x y
- @deffnx Instruction car x
- @deffnx Instruction cdr x
- @deffnx Instruction vector-ref x y
- @deffnx Instruction vector-set x n y
- @deffnx Instruction struct? x
- @deffnx Instruction struct-ref x n
- @deffnx Instruction struct-set x n v
- @deffnx Instruction struct-vtable x
- @deffnx Instruction class-of x
- @deffnx Instruction slot-ref struct n
- @deffnx Instruction slot-set struct n x
- Inlined implementations of their Scheme equivalents.
- @end deffn
- Note that @code{caddr} and friends compile to a series of @code{car}
- and @code{cdr} instructions.
- @node Inlined Mathematical Instructions
- @subsubsection Inlined Mathematical Instructions
- Inlining mathematical operations has the obvious advantage of handling
- fixnums without function calls or allocations. The trick, of course,
- is knowing when the result of an operation will be a fixnum, and there
- might be a couple bugs here.
- More instructions could be added here over time.
- As in the previous section, the definitions below show stack
- parameters instead of instruction stream parameters.
- @deffn Instruction add x y
- @deffnx Instruction add1 x
- @deffnx Instruction sub x y
- @deffnx Instruction sub1 x
- @deffnx Instruction mul x y
- @deffnx Instruction div x y
- @deffnx Instruction quo x y
- @deffnx Instruction rem x y
- @deffnx Instruction mod x y
- @deffnx Instruction ee? x y
- @deffnx Instruction lt? x y
- @deffnx Instruction gt? x y
- @deffnx Instruction le? x y
- @deffnx Instruction ge? x y
- @deffnx Instruction ash x n
- @deffnx Instruction logand x y
- @deffnx Instruction logior x y
- @deffnx Instruction logxor x y
- Inlined implementations of the corresponding mathematical operations.
- @end deffn
- @node Inlined Bytevector Instructions
- @subsubsection Inlined Bytevector Instructions
- Bytevector operations correspond closely to what the current hardware
- can do, so it makes sense to inline them to VM instructions, providing
- a clear path for eventual native compilation. Without this, Scheme
- programs would need other primitives for accessing raw bytes -- but
- these primitives are as good as any.
- As in the previous section, the definitions below show stack
- parameters instead of instruction stream parameters.
- The multibyte formats (@code{u16}, @code{f64}, etc) take an extra
- endianness argument. Only aligned native accesses are currently
- fast-pathed in Guile's VM.
- @deffn Instruction bv-u8-ref bv n
- @deffnx Instruction bv-s8-ref bv n
- @deffnx Instruction bv-u16-native-ref bv n
- @deffnx Instruction bv-s16-native-ref bv n
- @deffnx Instruction bv-u32-native-ref bv n
- @deffnx Instruction bv-s32-native-ref bv n
- @deffnx Instruction bv-u64-native-ref bv n
- @deffnx Instruction bv-s64-native-ref bv n
- @deffnx Instruction bv-f32-native-ref bv n
- @deffnx Instruction bv-f64-native-ref bv n
- @deffnx Instruction bv-u16-ref bv n endianness
- @deffnx Instruction bv-s16-ref bv n endianness
- @deffnx Instruction bv-u32-ref bv n endianness
- @deffnx Instruction bv-s32-ref bv n endianness
- @deffnx Instruction bv-u64-ref bv n endianness
- @deffnx Instruction bv-s64-ref bv n endianness
- @deffnx Instruction bv-f32-ref bv n endianness
- @deffnx Instruction bv-f64-ref bv n endianness
- @deffnx Instruction bv-u8-set bv n val
- @deffnx Instruction bv-s8-set bv n val
- @deffnx Instruction bv-u16-native-set bv n val
- @deffnx Instruction bv-s16-native-set bv n val
- @deffnx Instruction bv-u32-native-set bv n val
- @deffnx Instruction bv-s32-native-set bv n val
- @deffnx Instruction bv-u64-native-set bv n val
- @deffnx Instruction bv-s64-native-set bv n val
- @deffnx Instruction bv-f32-native-set bv n val
- @deffnx Instruction bv-f64-native-set bv n val
- @deffnx Instruction bv-u16-set bv n val endianness
- @deffnx Instruction bv-s16-set bv n val endianness
- @deffnx Instruction bv-u32-set bv n val endianness
- @deffnx Instruction bv-s32-set bv n val endianness
- @deffnx Instruction bv-u64-set bv n val endianness
- @deffnx Instruction bv-s64-set bv n val endianness
- @deffnx Instruction bv-f32-set bv n val endianness
- @deffnx Instruction bv-f64-set bv n val endianness
- Inlined implementations of the corresponding bytevector operations.
- @end deffn
|