Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Errata for:
Warren's Abstract Machine: A Tutorial Reconstruction
Hassan Ait-Kaci
MIT Press, Cambridge, MA
1991
ISBN 0-262-51058-8 (paper)
ISBN 0-262-01123-9 (cloth)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I am enclosing below the most up-to-date list of typos, bugs, and their -
easy - fixes... Anything else that you will find, please report back to
me. Who knows, one day when my stack is finally empty (ha!), I'll work on a
second edition with extensions. In the mean time, please accept my
apologies for your painful reading. On the other hand, my book's bugs and
typos are a wonderful indicator of who did or not actually try to implement
the code therein!
These bug reports and fixes are to be credited to James Anhalt III
(anhalt@cs.ucla.edu), Dan Friedman (dfried@cs.indiana.edu), Michael Levy
(mlevy@csr.uvic.ca), Donald A. Smith (dsmith@chaos.cs.brandeis.edu), and
Neng Fa Zhou (zhou@csce.kyushu-u.ac.jp). Big thanks to all.
-hak ___________________________________________________________________
Hassan Ait-Kaci, Professor
___________________________________________________________________
School of Computing Science phone: +1 (604) 291 55 89
Simon Fraser University fax: +1 (604) 291 30 45
Burnaby, British Columbia email: hak@cs.sfu.ca
V5A 1S6, Canada url: http://www.isg.sfu.ca/~hak/
___________________________________________________________________
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
In the definition of get_structure (fig 2.6, page 13) S should be
initialized to 1 before exiting get_structure in either READ or WRITE
modes.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
There is a problem with stack frames allocation. Namely, the book defines
ALLOCATE as:
(*) if E > B
then newE <- E + CODE[STACK[E + 1] - 1] + 2
else ...
While this should be:
(**) if E > B
then newE <- E + CODE[CP - 1] + 2
else ...
The following code shows why:
a/0 allocate
...
call b/0,1
L1 ...
b/0 allocate
...
call c/0,3
L2 ...
c/0 allocate
...
Now when b/0 calls c/0 the stack should look like:
|-------|
|CE: |0 <- a's environment
|-------|
|CP: |1
|-------|
|Y1: |2
|-------|
E -> |CE: 0 |3 <- b's environment
|-------|
|CP: L1 |4
|-------|
|Y1: |5
|-------|
|Y2: |6
|-------|
|Y3: |7
|-------|
| |8 <- we want c's environment to start here
|-------|
| |9
|-------|
CP = L2
P = c/0
So when c/0 executes allocate ...
With (*) the new value of E would be:
E = 3 + CODE[STACK[3 + 1] - 1] + 2
E = 3 + CODE[L1 - 1] + 2
E = 3 + 1 + 2
E = 6
which overwrites Y2 and Y3 since it uses the 1 from a/0
Whereas (**) gives us:
E = 3 + CODE[CP - 1] + 2
E = 3 + CODE[L2 - 1] + 2
E = 3 + 3 + 2
E = 8
which is right since b/0 wants to save 3 locals
This same problem exists in all the instructions that deal with
allocating new stack frames.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
As described UNIFY_CONSTANT does not increment the S register, this
makes it very hard to read structures with constants which are not the
last argument. Easy fix...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
When allocating a new choice or environment frame on the stack, one
should use CP (the continuation pointer) insteads of E+1 (the stored
continuation pointer) to find out the number of Y variables to preserve
in the previous environment frame. This is because the continuation
pointer is stored on the stack only if an ALLOCATE instruction is used
and so only CP has the real value.
Thus, instead of
if (E > B)
NewB = E + *(((int *) *(E+1))-1) + 2;
else NewB = B + *B + FIXED_CHOICE_FRAME_SIZE;
one should use code like
if (E > B)
NewB = E + *(CP-1) + 2;
else NewB = B + *B + FIXED_CHOICE_FRAME_SIZE;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The try, retry, and trust instructions reset the HB register to an
incorrect value. The problem is that n is computed from the original
value of B (n <- STACK[B]). Hence n is no longer valid when HB is
re-loaded. The correct code is:
HB <- STACK[B+STACK[B]+6]
There is a more subtle related bug that usually doesn't matter very
much: both cut and neck_cut should also reset HB. If they do not,
some uneccessary trailing will occur. This normally doesnt matter
too much (aside from a small performance penalty), but it does turn
out to be a problem if you try to implement Older and Rummel's incremental
garbage collection algorithm, because you end up with dangling trail
references to collected heap storage. O&R's algorithm relies on knowing
that there are no trail references below a certain point into the
tip of the heap.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%