Skip to content

Commit 333eb46

Browse files
authored
Ch5 minor improvements (#141)
* Add bibliography ref to WAM * Add links to code/modules * Format: use monospace for code related parts
1 parent 18e756b commit 333eb46

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

book.asciidoc

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ include::chapters/ap-beam_instructions.asciidoc[]
7676

7777
include::chapters/ap-code_listings.asciidoc[]
7878

79+
[[bibliography]]
80+
include::chapters/references.asciidoc[]
7981

8082
//[index]
8183
//include::chapters/index.asciidoc[]

chapters/beam.asciidoc

+26-24
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ components.
2424

2525
=== Working Memory: A stack machine, it is not
2626

27-
As opposed to its predecessor Jam (Joe's Abstract Machine) which was a
27+
As opposed to its predecessor JAM (Joe's Abstract Machine) which was a
2828
stack machine, the BEAM is a register machine loosely based on WAM
29-
(TODO: cite). In a stack machine each operand to an instruction is
29+
<<warren>>. In a stack machine each operand to an instruction is
3030
first pushed to the working stack, then the instruction pops its
3131
arguments and then it pushes the result on the stack.
3232

@@ -49,8 +49,9 @@ add
4949

5050
This code can be generated directly from the parse tree of
5151
the expression. By using Erlang expression and the modules
52-
+erl_scan+ and +erl_parse+ we can build the world's most simplistic
53-
compiler.
52+
https://erlang.org/doc/man/erl_scan.html[+erl_scan+] and
53+
https://erlang.org/doc/man/erl_parse.html[+erl_parse+] we
54+
can build the world's most simplistic compiler.
5455

5556
[source,erlang]
5657
-------------------------------------------
@@ -177,16 +178,16 @@ Then we get the following code for the add function:
177178
------------------------------------------
178179

179180
Here we can see that the code (starting at label 2) first allocates a
180-
stack slot, to get space to save the argument _B_ over the function
181-
call _id(A)_. The value is then saved by the instruction
182-
_{move,{x,1},{y,0}}_ (read as move x1 to y0 or in imperative style: y0
183-
:= x1).
181+
stack slot, to get space to save the argument `B` over the function
182+
call `id(A)`. The value is then saved by the instruction
183+
`{move,{x,1},{y,0}}` (read as move `x1` to `y0` or in imperative style: `y0
184+
:= x1`).
184185

185186
The id function (at label f4) is then called by
186-
_{call,1,{f,4}}_. (We will come back to what the argument "1" stands for later.)
187-
Then the result of the call (now in X0)
188-
needs to be saved on the stack (Y0), but the argument _B_
189-
is saved in Y0 so the BEAM does a bit of shuffling:
187+
`{call,1,{f,4}}`. (We will come back to what the argument "1" stands for later.)
188+
Then the result of the call (now in `X0`)
189+
needs to be saved on the stack (`Y0`), but the argument `B`
190+
is saved in `Y0` so the BEAM does a bit of shuffling:
190191

191192
Except for the x and y registers, there are a number of special
192193
purpose registers:
@@ -208,12 +209,12 @@ fields in the PCB.
208209
{move,{x,1},{y,0}}. % y0 := x1 (id(A))
209210
------------------------------------------
210211

211-
Now we have the second argument _B_ in x0 (the first
212-
argument register) and we can call the _id_ function
213-
again _{call,1,{f,4}}_.
212+
Now we have the second argument `B` in `x0` (the first
213+
argument register) and we can call the `id` function
214+
again `{call,1,{f,4}}`.
214215

215-
After the call x0 contains _id(B)_ and y0 contains _id(A)_,
216-
now we can do the addition: _{gc_bif,'+',{f,0},1,[{y,0},{x,0}],{x,0}}_.
216+
After the call x0 contains `id(B)` and `y0` contains `id(A)`,
217+
now we can do the addition: `{gc_bif,'+',{f,0},1,[{y,0},{x,0}],{x,0}}`.
217218
(We will go into the details of BIF calls and GC later.)
218219

219220
=== Dispatch: Directly Threaded Code
@@ -297,7 +298,7 @@ int run(char *code) {
297298
You see, a virtual machine written in C does not need to
298299
be very complicated. This machine is just a loop checking
299300
the byte code at each instruction by looking at the value
300-
pointed to by the _instruction pointer _ (ip).
301+
pointed to by the _instruction pointer_ (`ip`).
301302

302303
For each byte code instruction it will switch on the instruction byte
303304
code and jump to the case which executes the instruction. This
@@ -424,7 +425,7 @@ values".
424425
We will look closer at the BEAM emulator later but we will take a
425426
quick look at how the add instruction is implemented. The code is
426427
somewhat hard to follow due to the heavy usage of macros. The
427-
STORE_ARITH_RESULT macro actually hides the dispatch function which
428+
`STORE_ARITH_RESULT` macro actually hides the dispatch function which
428429
looks something like: `I += 4; Goto(*I);`.
429430

430431
[source, C]
@@ -496,10 +497,10 @@ in this code:
496497
{move,{x,1},{y,0}}.
497498
-------------------------------------------
498499

499-
This code first saves the return value of the function call (x0) in a
500-
new register (x1). Then it moves the caller saves register (y0) to
501-
the first argument register (x0). Finally it moves the saved value in
502-
x1 to the caller save register (y0) so that it will survive the next
500+
This code first saves the return value of the function call (`x0`) in a
501+
new register (`x1`). Then it moves the caller saves register (`y0`) to
502+
the first argument register (`x0`). Finally it moves the saved value in
503+
x1 to the caller save register (`y0`) so that it will survive the next
503504
function call.
504505

505506
Imagine that we would implement three instruction in BEAM called
@@ -633,7 +634,8 @@ need to do explicit memory management. On the BEAM level, though, the
633634
code is responsible for checking for stack and heap overrun, and for
634635
allocating enough space on the stack and the heap.
635636

636-
The BEAM instruction +test_heap+ will ensure that there is as much
637+
The BEAM instruction https://github.com/erlang/otp/blob/OTP-23.0/lib/compiler/src/genop.tab#L118[+test_heap+]
638+
will ensure that there is as much
637639
space on the heap as requested. If needed the instruction will call
638640
the garbage collector to reclaim space on the heap. The garbage
639641
collector in turn will call the lower levels of the memory subsystem

0 commit comments

Comments
 (0)