492 \multicolumn{3}{l}{$\qquad\phantom{(}@\; \text{goto}\;l_{wbegin}$}\\ |
492 \multicolumn{3}{l}{$\qquad\phantom{(}@\; \text{goto}\;l_{wbegin}$}\\ |
493 \multicolumn{3}{l}{$\qquad\phantom{(}@\;L_{wend}:, E')$}\\ |
493 \multicolumn{3}{l}{$\qquad\phantom{(}@\;L_{wend}:, E')$}\\ |
494 \end{tabular} |
494 \end{tabular} |
495 \end{center} |
495 \end{center} |
496 |
496 |
497 Next we need to consider the statement \pcode{write x}, which |
497 Next we need to consider the statement \pcode{write x}, which |
498 can be used to write out the content of a variable. For this |
498 can be used to write out the content of a variable. For this |
499 we need to use a Java library function. In order to avoid |
499 we need to use a Java library function. In order to avoid |
500 having to generate a lot of code for each |
500 having to generate a lot of code for each |
501 \pcode{write}-command, we use a separate method and just call |
501 \pcode{write}-command, we use a separate method and just call |
502 this method with an appropriate stack. |
502 this method with an argument (which needs to be placed on the |
|
503 stack). The code is as follows. |
|
504 |
503 |
505 |
504 \begin{lstlisting}[language=JVMIS] |
506 \begin{lstlisting}[language=JVMIS] |
505 .method public static write(I)V |
507 .method public static write(I)V |
506 .limit locals 5 |
508 .limit locals 1 |
507 .limit stack 5 |
509 .limit stack 2 |
508 getstatic java/lang/System/out Ljava/io/PrintStream; |
510 getstatic java/lang/System/out Ljava/io/PrintStream; |
509 iload 0 |
511 iload 0 |
510 invokevirtual java/io/PrintStream/println(I)V |
512 invokevirtual java/io/PrintStream/println(I)V |
511 return |
513 return |
512 .end method |
514 .end method |
513 \end{lstlisting} |
515 \end{lstlisting} |
514 |
516 |
|
517 \noindent The first line marks the beginning of the method, |
|
518 called \pcode{write}. It takes a single integer argument |
|
519 indicated by the \pcode{(I)} and returns no result, indicated |
|
520 by the \pcode{V}. Since the method has only one argument, we |
|
521 only need a single local variable (Line~2) and a stack with |
|
522 two cells will be sufficient (Line 3). Line 4 instructs the |
|
523 JVM to get the value of the field \pcode{out} of the class |
|
524 \pcode{java/lang/System}. It expects the value to be of type |
|
525 \pcode{java/io/PrintStream}. A reference to this value will be |
|
526 placed on the stack. Line~5 copies the integer we want to |
|
527 print out onto the stack. In the next line we call the method |
|
528 \pcode{println} (from the class \pcode{java/io/PrintStream}). |
|
529 We want to print out an integer and do not expect anything |
|
530 back (that is why the type annotation \pcode{(I)V}). The |
|
531 \pcode{return}-instruction in the next line changes the |
|
532 control-flow back to the place from where \pcode{write} was |
|
533 called. This method needs to be part of a header that is |
|
534 included in any code we generate. The method \pcode{write} can |
|
535 be invoked with the two instructions |
|
536 |
|
537 \begin{lstlisting}[mathescape,language=JVMIS] |
|
538 iload $E(x)$ |
|
539 invokestatic XXX/XXX/write(I)V |
|
540 \end{lstlisting} |
|
541 |
|
542 \noindent where we first place the variable to be printed on |
|
543 the stack and then call \pcode{write}. The \pcode{XXX} need to |
|
544 be replaced by appropriate class name (this will be explained |
|
545 shortly). |
|
546 |
|
547 |
|
548 \begin{figure}[t] |
|
549 \begin{lstlisting}[mathescape,language=JVMIS] |
|
550 .class public XXX.XXX |
|
551 .super java/lang/Object |
|
552 |
|
553 .method public <init>()V |
|
554 aload_0 |
|
555 invokenonvirtual java/lang/Object/<init>()V |
|
556 return |
|
557 .end method |
|
558 |
|
559 .method public static main([Ljava/lang/String;)V |
|
560 .limit locals 200 |
|
561 .limit stack 200 |
|
562 |
|
563 $\textit{\ldots{}here comes the compiled code\ldots}$ |
|
564 |
|
565 return |
|
566 .end method |
|
567 \end{lstlisting} |
|
568 \caption{Boilerplate code needed for running generated code.\label{boiler}} |
|
569 \end{figure} |
|
570 |
|
571 |
|
572 By generating code for a While-program, we end up with a list |
|
573 of (JVM assembly) instructions. Unfortunately, there is a bit |
|
574 more boilerplate code needed before these instructions can be |
|
575 run. The code is shown in Figure~\ref{boiler}. This |
|
576 boilerplate code is very specific to the JVM. Lines 4 to 8 |
|
577 contains a method for object creation in the JVM and is called |
|
578 \emph{before} the \pcode{main}-method in Lines 10 to 17. |
|
579 Interesting are the Lines 11 and 12 where we hardwire that the |
|
580 stack of our program will never be larger than 200 and that |
|
581 the maximum number of variables is also 200. This seem |
|
582 conservative default values that allow is to run some simple |
|
583 While-programs. In a real compiler, we would of course need to |
|
584 work harder and find out appropriate values for the stack and |
|
585 local variables. |
|
586 |
|
587 |
515 \end{document} |
588 \end{document} |
516 |
589 |
517 %%% Local Variables: |
590 %%% Local Variables: |
518 %%% mode: latex |
591 %%% mode: latex |
519 %%% TeX-master: t |
592 %%% TeX-master: t |