diff -r b018234c9126 -r 0e25fb72d339 handouts/ho07.tex --- a/handouts/ho07.tex Tue Nov 17 04:02:08 2015 +0000 +++ b/handouts/ho07.tex Tue Nov 17 04:38:01 2015 +0000 @@ -488,17 +488,19 @@ \end{tabular} \end{center} -Next we need to consider the statement \pcode{write x}, which -can be used to write out the content of a variable. For this +Next we need to consider the statement \pcode{write x}, which +can be used to write out the content of a variable. For this we need to use a Java library function. In order to avoid -having to generate a lot of code for each +having to generate a lot of code for each \pcode{write}-command, we use a separate method and just call -this method with an appropriate stack. +this method with an argument (which needs to be placed on the +stack). The code is as follows. + \begin{lstlisting}[language=JVMIS] .method public static write(I)V - .limit locals 5 - .limit stack 5 + .limit locals 1 + .limit stack 2 getstatic java/lang/System/out Ljava/io/PrintStream; iload 0 invokevirtual java/io/PrintStream/println(I)V @@ -506,6 +508,77 @@ .end method \end{lstlisting} +\noindent The first line marks the beginning of the method, +called \pcode{write}. It takes a single integer argument +indicated by the \pcode{(I)} and returns no result, indicated +by the \pcode{V}. Since the method has only one argument, we +only need a single local variable (Line~2) and a stack with +two cells will be sufficient (Line 3). Line 4 instructs the +JVM to get the value of the field \pcode{out} of the class +\pcode{java/lang/System}. It expects the value to be of type +\pcode{java/io/PrintStream}. A reference to this value will be +placed on the stack. Line~5 copies the integer we want to +print out onto the stack. In the next line we call the method +\pcode{println} (from the class \pcode{java/io/PrintStream}). +We want to print out an integer and do not expect anything +back (that is why the type annotation \pcode{(I)V}). The +\pcode{return}-instruction in the next line changes the +control-flow back to the place from where \pcode{write} was +called. This method needs to be part of a header that is +included in any code we generate. The method \pcode{write} can +be invoked with the two instructions + +\begin{lstlisting}[mathescape,language=JVMIS] +iload $E(x)$ +invokestatic XXX/XXX/write(I)V +\end{lstlisting} + +\noindent where we first place the variable to be printed on +the stack and then call \pcode{write}. The \pcode{XXX} need to +be replaced by appropriate class name (this will be explained +shortly). + + +\begin{figure}[t] +\begin{lstlisting}[mathescape,language=JVMIS] +.class public XXX.XXX +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public static main([Ljava/lang/String;)V + .limit locals 200 + .limit stack 200 + + $\textit{\ldots{}here comes the compiled code\ldots}$ + + return +.end method +\end{lstlisting} +\caption{Boilerplate code needed for running generated code.\label{boiler}} +\end{figure} + + +By generating code for a While-program, we end up with a list +of (JVM assembly) instructions. Unfortunately, there is a bit +more boilerplate code needed before these instructions can be +run. The code is shown in Figure~\ref{boiler}. This +boilerplate code is very specific to the JVM. Lines 4 to 8 +contains a method for object creation in the JVM and is called +\emph{before} the \pcode{main}-method in Lines 10 to 17. +Interesting are the Lines 11 and 12 where we hardwire that the +stack of our program will never be larger than 200 and that +the maximum number of variables is also 200. This seem +conservative default values that allow is to run some simple +While-programs. In a real compiler, we would of course need to +work harder and find out appropriate values for the stack and +local variables. + + \end{document} %%% Local Variables: