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));
/* Upon normal execution we jump behind exception handler,
* the target address is not known yet.
*/
GOTO g = new GOTO(null);
InstructionHandle try_end = il.append(g);
/* } catch() { ... }
* Add exception handler: print exception and return from method
*/
InstructionHandle handler =
il.append(factory.createFieldAccess("java.lang.System", "out", p_stream,
Constants.GETSTATIC));
// Little trick in order not to save exception object temporarily
il.append(InstructionConstants.SWAP);
il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID,
new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL));
il.append(InstructionConstants.RETURN);
mg.addExceptionHandler(try_start, try_end, handler,
new ObjectType("java.io.IOException"));
/* Normal code continues, now we can set the branch target of the GOTO
* that jumps over the handler code.
*/
InstructionHandle ih =
il.append(factory.createFieldAccess("java.lang.System", "out", p_stream,
Constants.GETSTATIC));
g.setTarget(ih);
/* String concatenation compiles to StringBuffer operations.
*/
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));
/* Concatenate strings using a StringBuffer and print them.
*/
il.append(factory.createInvoke("java.lang.StringBuffer", "append",
Type.STRINGBUFFER, new Type[] { Type.STRING },