|
@@ -4661,16 +4661,18 @@ paragraphs. The register \code{rax} is for the return value of the
|
|
function.
|
|
function.
|
|
|
|
|
|
Recall from Section~\ref{sec:x86} that the stack is also used for
|
|
Recall from Section~\ref{sec:x86} that the stack is also used for
|
|
-local variables, and that at the beginning of a function we move the
|
|
|
|
-stack pointer \code{rsp} down to make room for them. To make
|
|
|
|
-additional room for passing arguments, we shall move the stack pointer
|
|
|
|
-even further down. We count how many stack arguments are needed for
|
|
|
|
-each function call that occurs inside the body of the function and
|
|
|
|
-find their maximum. Adding this number to the number of local variables
|
|
|
|
-gives us how much the \code{rsp} should be moved at the beginning of
|
|
|
|
-the function. In preparation for a function call, we offset from
|
|
|
|
-\code{rsp} to set up the stack arguments. We put the first stack
|
|
|
|
-argument in \code{0(\%rsp)}, the second in \code{8(\%rsp)}, and so on.
|
|
|
|
|
|
+local variables and for storing the values of caller-save registers
|
|
|
|
+(we shall refer to all of these collectively as ``locals''), and that
|
|
|
|
+at the beginning of a function we move the stack pointer \code{rsp}
|
|
|
|
+down to make room for them. To make additional room for passing
|
|
|
|
+arguments, we shall move the stack pointer even further down. We count
|
|
|
|
+how many stack arguments are needed for each function call that occurs
|
|
|
|
+inside the body of the function and find their maximum. Adding this
|
|
|
|
+number to the number of locals gives us how much the \code{rsp} should
|
|
|
|
+be moved at the beginning of the function. In preparation for a
|
|
|
|
+function call, we offset from \code{rsp} to set up the stack
|
|
|
|
+arguments. We put the first stack argument in \code{0(\%rsp)}, the
|
|
|
|
+second in \code{8(\%rsp)}, and so on.
|
|
|
|
|
|
Upon calling the function, the stack arguments are retrieved by the
|
|
Upon calling the function, the stack arguments are retrieved by the
|
|
callee using the base pointer \code{rbp}. The address \code{16(\%rbp)}
|
|
callee using the base pointer \code{rbp}. The address \code{16(\%rbp)}
|
|
@@ -4699,18 +4701,18 @@ caller.
|
|
Caller View & Callee View & Contents & Frame \\ \hline
|
|
Caller View & Callee View & Contents & Frame \\ \hline
|
|
8(\key{\%rbp}) & & return address & \multirow{5}{*}{Caller}\\
|
|
8(\key{\%rbp}) & & return address & \multirow{5}{*}{Caller}\\
|
|
0(\key{\%rbp}) & & old \key{rbp} \\
|
|
0(\key{\%rbp}) & & old \key{rbp} \\
|
|
--8(\key{\%rbp}) & & variable $1$ \\
|
|
|
|
|
|
+-8(\key{\%rbp}) & & local $1$ \\
|
|
\ldots & & \ldots \\
|
|
\ldots & & \ldots \\
|
|
-$-8k$(\key{\%rbp}) & & variable $k$ \\
|
|
|
|
|
|
+$-8k$(\key{\%rbp}) & & local $k$ \\
|
|
& & \\
|
|
& & \\
|
|
$8n-8$\key{(\%rsp)} & $8n+8$(\key{\%rbp})& argument $n$ \\
|
|
$8n-8$\key{(\%rsp)} & $8n+8$(\key{\%rbp})& argument $n$ \\
|
|
& \ldots & \ldots \\
|
|
& \ldots & \ldots \\
|
|
0\key{(\%rsp)} & 16(\key{\%rbp}) & argument $1$ & \\ \hline
|
|
0\key{(\%rsp)} & 16(\key{\%rbp}) & argument $1$ & \\ \hline
|
|
& 8(\key{\%rbp}) & return address & \multirow{5}{*}{Callee}\\
|
|
& 8(\key{\%rbp}) & return address & \multirow{5}{*}{Callee}\\
|
|
& 0(\key{\%rbp}) & old \key{rbp} \\
|
|
& 0(\key{\%rbp}) & old \key{rbp} \\
|
|
-& -8(\key{\%rbp}) & variable $1$ \\
|
|
|
|
|
|
+& -8(\key{\%rbp}) & local $1$ \\
|
|
& \ldots & \ldots \\
|
|
& \ldots & \ldots \\
|
|
-& $-8m$(\key{\%rsp}) & variable $m$\\ \hline
|
|
|
|
|
|
+& $-8m$(\key{\%rsp}) & local $m$\\ \hline
|
|
\end{tabular}
|
|
\end{tabular}
|
|
|
|
|
|
\caption{Memory layout of caller and callee frames.}
|
|
\caption{Memory layout of caller and callee frames.}
|
|
@@ -5017,9 +5019,9 @@ refer to variables defined outside the function. To identify such
|
|
variable occurences, we review the standard notion of free variable.
|
|
variable occurences, we review the standard notion of free variable.
|
|
|
|
|
|
\begin{definition}
|
|
\begin{definition}
|
|
-A variable is \textbf{\emph{free with respect to an expression}} $e$
|
|
|
|
-if the variable occurs inside $e$ but does not have an enclosing
|
|
|
|
-binding in $e$.
|
|
|
|
|
|
+A variable is \emph{free with respect to an expression} $e$ if the
|
|
|
|
+variable occurs inside $e$ but does not have an enclosing binding in
|
|
|
|
+$e$.
|
|
\end{definition}
|
|
\end{definition}
|
|
|
|
|
|
For example, the variables \code{x}, \code{y}, and \code{z} are all
|
|
For example, the variables \code{x}, \code{y}, and \code{z} are all
|
|
@@ -5038,9 +5040,24 @@ point where the \code{lambda} is applied. Referring again to
|
|
Figure~\ref{fig:lexical-scoping}, the binding of \code{x} to \code{5}
|
|
Figure~\ref{fig:lexical-scoping}, the binding of \code{x} to \code{5}
|
|
needs to be used in the application of \code{g} to \code{11}, but the
|
|
needs to be used in the application of \code{g} to \code{11}, but the
|
|
binding of \code{x} to \code{3} needs to be used in the application of
|
|
binding of \code{x} to \code{3} needs to be used in the application of
|
|
-\code{h} to \code{15}.
|
|
|
|
|
|
+\code{h} to \code{15}. The solution is to bundle the values of the
|
|
|
|
+free variables together with the function pointer for the lambda's
|
|
|
|
+code into a data structure called a \emph{closure}. Fortunately, we
|
|
|
|
+already have the appropriate ingredients to make closures,
|
|
|
|
+Chapter~\ref{ch:tuples} gave us tuples and Chapter~\ref{ch:functions}
|
|
|
|
+gave us function pointers. The function pointer shall reside at index
|
|
|
|
+$0$ and the values for free variables will fill in the rest of the
|
|
|
|
+tuple.
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+\begin{figure}[tbp]
|
|
|
|
+\centering \includegraphics[width=0.8\textwidth]{closures}
|
|
|
|
+\caption{Example closure representation for the \key{lambda}'s
|
|
|
|
+ in Figure~\ref{fig:lexical-scoping}.}
|
|
|
|
+\label{fig:tuple-rep}
|
|
|
|
+\end{figure}
|
|
|
|
+
|
|
|
|
|
|
-UNDER CONSTRUCTION
|
|
|
|
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
@@ -5052,6 +5069,27 @@ UNDER CONSTRUCTION
|
|
\label{ch:type-dynamic}
|
|
\label{ch:type-dynamic}
|
|
|
|
|
|
|
|
|
|
|
|
+\begin{figure}[tbp]
|
|
|
|
+\centering
|
|
|
|
+\fbox{
|
|
|
|
+\begin{minipage}{0.96\textwidth}
|
|
|
|
+\[
|
|
|
|
+\begin{array}{lcl}
|
|
|
|
+ \Type &::=& \ldots \mid \key{Any} \\
|
|
|
|
+ \Exp &::=& \ldots \mid (\key{inject}\; \Exp \; \Type) \mid (\key{project}\;\Exp\;\Type)\\
|
|
|
|
+ \Def &::=& \ldots \\
|
|
|
|
+ R_4 &::=& (\key{program} \; \Def^{*} \; \Exp)
|
|
|
|
+\end{array}
|
|
|
|
+\]
|
|
|
|
+\end{minipage}
|
|
|
|
+}
|
|
|
|
+\caption{The $R_6$ language, an extension of $R_5$
|
|
|
|
+ (Figure~\ref{fig:r5-syntax}).}
|
|
|
|
+\label{fig:r6-syntax}
|
|
|
|
+\end{figure}
|
|
|
|
+
|
|
|
|
+Figure~\ref{fig:r6-syntax}
|
|
|
|
+
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\chapter{Parametric Polymorphism}
|
|
\chapter{Parametric Polymorphism}
|
|
\label{ch:parametric-polymorphism}
|
|
\label{ch:parametric-polymorphism}
|