\section{Code examples for the BCEL API}\label{sec:apicg}

\subsection{HelloWorldBuilder.java}
The following Java program reads a name from the standard input and
prints a friendly ``Hello''. Since the \texttt{readLine()} method may
throw an \texttt{IOException} it is enclosed by a \texttt{try-catch} block.

{\small \verbatimtabinput{HelloWorld.java}\label{sec:hello}}

\subsection{HelloWorldBuilder.java}

We will sketch  here how the above Java class can  be created from the
scratch  using the \jc API. For ease of reading we will
use textual signatures and not create them dynamically. For example,
the signature

\begin{verbatim}
  "(Ljava/lang/String;)Ljava/lang/StringBuffer;"
\end{verbatim}

would actually be created with

\begin{verbatim}
  Type.getMethodSignature(Type.STRINGBUFFER, new Type[] { Type.STRING });
\end{verbatim}

\subsubsection{Initialization:}

First we create an empty class and an instruction list:

{\small\begin{verbatim}
  ClassGen  cg = new ClassGen("HelloWorld", "java.lang.Object",
                              "<generated>", ACC_PUBLIC | ACC_SUPER,
                              null);
  ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
  InstructionList il = new InstructionList();
\end{verbatim}}

We then create the main method, supplying the method's name and the
symbolic type signature encoded with \texttt{Type} objects.

{\small\begin{verbatim}
  MethodGen  mg = new MethodGen(ACC_STATIC | ACC_PUBLIC,// access flags
                                Type.VOID,              // return type
                                new Type[] {            // argument types
                                  new ArrayType(Type.STRING, 1) },
                                new String[] { "argv" }, // arg names
                                "main", "HelloWorld",    // method, class
                                il, cp);
  InstructionFactory factory = new InstructionFactory(cg);
\end{verbatim}}

We define some often used types:

{\small\begin{verbatim}
  ObjectType i_stream = new ObjectType("java.io.InputStream");
  ObjectType p_stream = new ObjectType("java.io.PrintStream");
\end{verbatim}}

\subsubsection{Create variables \texttt{in} and \texttt{name}:}

We call the           constructors,              i.e.              execute
\texttt{BufferedReader(Input\-Stream\-Reader(System.in))}.  The  reference
to the \texttt{BufferedReader} object stays on top of the stack and is
stored in the newly allocated \texttt{in} variable.

{\small\begin{verbatim}
  il.append(factory.createNew("java.io.BufferedReader"));
  il.append(InstructionConstants.DUP); // Use predefined constant
  il.append(factory.createNew("java.io.InputStreamReader"));
  il.append(InstructionConstants.DUP);
  il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,
                                      Constants.GETSTATIC));
  il.append(factory.createInvoke("java.io.InputStreamReader", "<init>",
                                 Type.VOID, new Type[] { i_stream },
                                 Constants.INVOKESPECIAL));
  il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID,
                                 new Type[] {new ObjectType("java.io.Reader")},
                                 Constants.INVOKESPECIAL));

  LocalVariableGen lg =
    mg.addLocalVariable("in",
                        new ObjectType("java.io.BufferedReader"), null, null);
  int in = lg.getIndex();
  lg.setStart(il.append(new ASTORE(in))); // `i' valid from here
\end{verbatim}}

Create local variable \texttt{name} and  initialize it to \texttt{null}.

{\small\begin{verbatim}
  lg = mg.addLocalVariable("name", Type.STRING, null, null);
  int name = lg.getIndex();
  il.append(InstructionConstants.ACONST_NULL);
  lg.setStart(il.append(new ASTORE(name))); // `name' valid from here
\end{verbatim}}

\subsubsection{Create try-catch block}

We remember  the start  of the  block, read a  line from  the standard
input and store it into the variable \texttt{name}.

{\small\begin{verbatim}
  InstructionHandle try_start =
    il.append(factory.createFieldAccess("java.lang.System", "out", p_stream,
                                        Constants.GETSTATIC));

  il.append(new PUSH(cp, "Please enter your name> "));
  il.append(factory.createInvoke("java.io.PrintStream", "print", Type.VOID, 
                                 new Type[] { Type.STRING },
                                 Constants.INVOKEVIRTUAL));
  il.append(new ALOAD(in));
  il.append(factory.createInvoke("java.io.BufferedReader", "readLine",
                                 Type.STRING, Type.NO_ARGS,
                                 Constants.INVOKEVIRTUAL));
  il.append(new ASTORE(name));
\end{verbatim}}

Upon  normal execution we  jump behind  exception handler,  the target
address is not known yet.

{\small\begin{verbatim}
  GOTO g = new GOTO(null);
  InstructionHandle try_end = il.append(g);
\end{verbatim}}

We add the exception handler which simply returns from the method.

{\small\begin{verbatim}
  InstructionHandle handler = il.append(InstructionConstants.RETURN);
  mg.addExceptionHandler(try_start, try_end, handler, "java.io.IOException");
\end{verbatim}}

``Normal'' code continues, now we can set the branch target of the GOTO.

{\small\begin{verbatim}
  InstructionHandle ih =
    il.append(factory.createFieldAccess("java.lang.System", "out", p_stream,
                                        Constants.GETSTATIC));
  g.setTarget(ih);
\end{verbatim}}

\subsubsection{Printing "Hello"}

String concatenation compiles to \texttt{StringBuffer} operations.

{\small\begin{verbatim}
  il.append(factory.createNew(Type.STRINGBUFFER));
  il.append(InstructionConstants.DUP);
  il.append(new PUSH(cp, "Hello, "));
  il.append(factory.createInvoke("java.lang.StringBuffer", "<init>",
                                 Type.VOID, new Type[] { Type.STRING },
                                 Constants.INVOKESPECIAL));
  il.append(new ALOAD(name));
  il.append(factory.createInvoke("java.lang.StringBuffer", "append",
                                 Type.STRINGBUFFER, new Type[] { Type.STRING },
                                 Constants.INVOKEVIRTUAL));
  il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
                                 Type.STRING, Type.NO_ARGS,
                                 Constants.INVOKEVIRTUAL));
    
  il.append(factory.createInvoke("java.io.PrintStream", "println",
                                 Type.VOID, new Type[] { Type.STRING },
                                 Constants.INVOKEVIRTUAL));
  il.append(InstructionConstants.RETURN);
\end{verbatim}}

\subsubsection{Finalization}

Finally, we  have to  set  the stack  size,  which  normally would  be
computed on the fly and add a default constructor method to the class,
which is empty in this case.

{\small\begin{verbatim}
  mg.setMaxStack(5);
  cg.addMethod(mg.getMethod());
  il.dispose(); // Allow instruction handles to be reused
  cg.addEmptyConstructor(ACC_PUBLIC);
\end{verbatim}}

Last but not least we dump the \texttt{JavaClass} object to a file.

{\small\begin{verbatim}
  try {
    cg.getJavaClass().dump("HelloWorld.class");
  } catch(java.io.IOException e) { System.err.println(e); }
\end{verbatim}}

\subsection{Peephole.java}

This class implements a simple peephole optimizer that removes any NOP
instructions from the given class.

{\small\verbatimtabinput{Peephole.java}}\label{sec:nop}
