Jeremy Siek 6 年之前
父节点
当前提交
3aa14fd227
共有 1 个文件被更改,包括 53 次插入54 次删除
  1. 53 54
      book.tex

+ 53 - 54
book.tex

@@ -4075,12 +4075,15 @@ and test your compiler using your previously created programs on the
 
 \section{Patch Instructions}
 
+The second argument of the \key{cmpq} instruction must not be an
+immediate value (such as a literal integer). So if you are comparing
+two immediates, we recommend inserting a \key{movq} instruction to put
+the second argument in \key{rax}.
+%
+The second argument of the \key{movzbq} must be a register.
+%
 There are no special restrictions on the x86 instructions
-\key{jmp-if}, \key{jmp}, and \key{label}, but there is an unusual
-restriction on \key{cmpq}. The second argument is not allowed to be an
-immediate value (such as a literal integer). If you are comparing two
-immediates, you must insert another \key{movq} instruction to put the
-second argument in \key{rax}.
+\key{jmp-if}, \key{jmp}, and \key{label}. 
 
 \begin{exercise}\normalfont
 Update \code{patch-instructions} to handle the new x86 instructions.
@@ -4363,18 +4366,24 @@ UNDER CONSTRUCTION
 In this chapter we study the implementation of mutable tuples (called
 ``vectors'' in Racket). This language feature is the first to use the
 computer's \emph{heap} because the lifetime of a Racket tuple is
-indefinite, that is, a tuple does not follow a stack (FIFO) discipline
-but instead lives forever from the programmer's viewpoint. Of course,
-from an implementor's viewpoint, it is important to reclaim the space
-associated with tuples when they are no longer needed, which is why we
-also study \emph{garbage collection} techniques in this chapter.
+indefinite, that is, a tuple lives forever from the programmer's
+viewpoint. Of course, from an implementor's viewpoint, it is important
+to reclaim the space associated with a tuple when it is no longer
+needed, which is why we also study \emph{garbage collection}
+techniques in this chapter.
 
 Section~\ref{sec:r3} introduces the $R_3$ language including its
 interpreter and type checker. The $R_3$ language extends the $R_2$
-language of Chapter~\ref{ch:bool-types} with vectors and void values
-(because the \code{vector-set!}  operation returns a void
-value). Section~\ref{sec:GC} describes a garbage collection algorithm
-based on copying live objects back and forth between two halves of the
+language of Chapter~\ref{ch:bool-types} with vectors and Racket's
+``void'' value. The reason for including the later is that the
+\code{vector-set!} operation returns a value of type
+\code{Void}\footnote{This may sound contradictory, but Racket's
+  \code{Void} type corresponds to what is more commonly called the
+  \code{Unit} type. This type is inhabited by a single value that is
+  usually written \code{unit} or \code{()}\citep{Pierce:2002hj}.}.
+
+Section~\ref{sec:GC} describes a garbage collection algorithm based on
+copying live objects back and forth between two halves of the
 heap. The garbage collector requires coordination with the compiler so
 that it can see all of the \emph{root} pointers, that is, pointers in
 registers or on the procedure call stack.
@@ -4399,11 +4408,11 @@ $40$, to which we add the $2$, the element at index $0$ of the
 
 \begin{figure}[tbp]
 \begin{lstlisting}
-  (let ([t (vector 40 #t (vector 2))])
-    (if (vector-ref t 1)
-        (+ (vector-ref t 0)
-           (vector-ref (vector-ref t 2) 0))
-        44))
+    (let ([t (vector 40 #t (vector 2))])
+      (if (vector-ref t 1)
+          (+ (vector-ref t 0)
+             (vector-ref (vector-ref t 2) 0))
+          44))
 \end{lstlisting}
 \caption{Example program that creates tuples and reads from them.}
 \label{fig:vector-eg}
@@ -4446,10 +4455,10 @@ in which both \code{t1} and \code{t2} refer to the same tuple.  Thus,
 the mutation through \code{t2} is visible when referencing the tuple
 from \code{t1}, so the result of this program is \code{42}.
 \begin{lstlisting}
-(let ([t1 (vector 3 7)])
-  (let ([t2 t1])
-    (let ([_ (vector-set! t2 0 42)])
-      (vector-ref t1 0))))
+    (let ([t1 (vector 3 7)])
+      (let ([t2 t1])
+        (let ([_ (vector-set! t2 0 42)])
+          (vector-ref t1 0))))
 \end{lstlisting}
 
 The next issue concerns the lifetime of tuples. Of course, they are
@@ -4460,10 +4469,10 @@ is not tied to any notion of static scoping. For example, the
 following program returns \code{3} even though the variable \code{t}
 goes out of scope prior to accessing the vector.
 \begin{lstlisting}
-(vector-ref
-  (let ([t (vector 3 7)])
-    t)
-  0)
+    (vector-ref
+      (let ([t (vector 3 7)])
+        t)
+      0)
 \end{lstlisting}
 From the perspective of programmer-observable behavior, tuples live
 forever. Of course, if they really lived forever, then many programs
@@ -4481,13 +4490,13 @@ in Section~\ref{sec:GC}, we need to know which variables are pointers
 into the heap, that is, which variables are vectors. Also, when
 allocating a vector, we shall need to know which elements of the
 vector are pointers. We can obtain this information during type
-checking and flattening. The type checker in
+checking and when we uncover local variables. The type checker in
 Figure~\ref{fig:typecheck-R3} not only computes the type of an
 expression, it also wraps every sub-expression $e$ with the form
 $(\key{has-type}\; e\; T)$, where $T$ is $e$'s type. Subsequently, in
-the flatten pass (Section~\ref{sec:flatten-gc}) this type information is
-propagated to all variables (including temporaries generated during
-flattening).
+the \code{uncover-locals} pass (Section~\ref{sec:uncover-locals-gc})
+this type information is propagated to all variables (including the
+temporaries generated by \code{remove-complex-opera*}).
 
 \begin{figure}[tbp]
 \begin{lstlisting}
@@ -4512,7 +4521,6 @@ flattening).
 \label{fig:interp-R3}
 \end{figure}
 
-
 \begin{figure}[tbp]
 \begin{lstlisting}
 (define (type-check-exp env)
@@ -4521,39 +4529,30 @@ flattening).
     (match e
       ...
       ['(void) (values '(has-type (void) Void) 'Void)]
-      [`(vector ,(app recur e* t*) ...)
+      [`(vector ,es ...)
+       (define-values (e* t*) (for/lists (e* t*) ([e es])
+                                (recur e)))
        (let ([t `(Vector ,@t*)])
+         (debug "vector/type-check-exp finished vector" t)
          (values `(has-type (vector ,@e*) ,t) t))]
-      [`(vector-ref ,(app recur e t) ,i)
+      [`(vector-ref ,e ,i)
+       (define-values (e^ t) (recur e))
        (match t
          [`(Vector ,ts ...)
-          (unless (and (exact-nonnegative-integer? i)
-                       (i . < . (length ts)))
-                  (error 'type-check-exp "invalid index ~a" i))
+          (unless (and (exact-nonnegative-integer? i) (< i (length ts)))
+            (error 'type-check-exp "invalid index ~a" i))
           (let ([t (list-ref ts i)])
-            (values `(has-type (vector-ref ,e (has-type ,i Integer)) ,t)
+            (values `(has-type (vector-ref ,e^ (has-type ,i Integer)) ,t) 
                     t))]
          [else (error "expected a vector in vector-ref, not" t)])]
-      [`(vector-set! ,(app recur e-vec t-vec) ,i
-                     ,(app recur e-arg t-arg))
-       (match t-vec
-         [`(Vector ,ts ...)
-          (unless (and (exact-nonnegative-integer? i)
-                       (i . < . (length ts)))
-            (error 'type-check-exp "invalid index ~a" i))
-          (unless (equal? (list-ref ts i) t-arg)
-            (error 'type-check-exp "type mismatch in vector-set! ~a ~a"
-                   (list-ref ts i) t-arg))
-          (values `(has-type (vector-set! ,e-vec
-                                          (has-type ,i Integer)
-                                          ,e-arg) Void) 'Void)]
-         [else (error 'type-check-exp
-                      "expected a vector in vector-set!, not ~a" t-vec)])]
-      [`(eq? ,(app recur e1 t1) ,(app recur e2 t2))
+      [`(eq? ,arg1 ,arg2)
+       (define-values (e1 t1) (recur arg1))
+       (define-values (e2 t2) (recur arg2))
        (match* (t1 t2)
          [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))
           (values `(has-type (eq? ,e1 ,e2) Boolean) 'Boolean)]
          [(other wise) ((super type-check-exp env) e)])]
+      ...
       )))
 \end{lstlisting}
 \caption{Type checker for the $R_3$ language.}