xref: /aosp_15_r20/external/apache-commons-bcel/src/examples/HelloWorldBuilder.java (revision 0c56280ab0842982c46a149f7b9eaa497e31e292)
1*0c56280aSSorin Basca /*
2*0c56280aSSorin Basca  * Licensed to the Apache Software Foundation (ASF) under one or more
3*0c56280aSSorin Basca  * contributor license agreements.  See the NOTICE file distributed with
4*0c56280aSSorin Basca  * this work for additional information regarding copyright ownership.
5*0c56280aSSorin Basca  * The ASF licenses this file to You under the Apache License, Version 2.0
6*0c56280aSSorin Basca  * (the "License"); you may not use this file except in compliance with
7*0c56280aSSorin Basca  * the License.  You may obtain a copy of the License at
8*0c56280aSSorin Basca  *
9*0c56280aSSorin Basca  *      http://www.apache.org/licenses/LICENSE-2.0
10*0c56280aSSorin Basca  *
11*0c56280aSSorin Basca  *  Unless required by applicable law or agreed to in writing, software
12*0c56280aSSorin Basca  *  distributed under the License is distributed on an "AS IS" BASIS,
13*0c56280aSSorin Basca  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*0c56280aSSorin Basca  *  See the License for the specific language governing permissions and
15*0c56280aSSorin Basca  *  limitations under the License.
16*0c56280aSSorin Basca  *
17*0c56280aSSorin Basca  */
18*0c56280aSSorin Basca 
19*0c56280aSSorin Basca import java.io.IOException;
20*0c56280aSSorin Basca 
21*0c56280aSSorin Basca import org.apache.bcel.Constants;
22*0c56280aSSorin Basca import org.apache.bcel.generic.ALOAD;
23*0c56280aSSorin Basca import org.apache.bcel.generic.ASTORE;
24*0c56280aSSorin Basca import org.apache.bcel.generic.ArrayType;
25*0c56280aSSorin Basca import org.apache.bcel.generic.ClassGen;
26*0c56280aSSorin Basca import org.apache.bcel.generic.ConstantPoolGen;
27*0c56280aSSorin Basca import org.apache.bcel.generic.GOTO;
28*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionConstants;
29*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionFactory;
30*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionHandle;
31*0c56280aSSorin Basca import org.apache.bcel.generic.InstructionList;
32*0c56280aSSorin Basca import org.apache.bcel.generic.LocalVariableGen;
33*0c56280aSSorin Basca import org.apache.bcel.generic.MethodGen;
34*0c56280aSSorin Basca import org.apache.bcel.generic.ObjectType;
35*0c56280aSSorin Basca import org.apache.bcel.generic.PUSH;
36*0c56280aSSorin Basca import org.apache.bcel.generic.Type;
37*0c56280aSSorin Basca 
38*0c56280aSSorin Basca /**
39*0c56280aSSorin Basca  * Create HelloWorld class:
40*0c56280aSSorin Basca  * <PRE>
41*0c56280aSSorin Basca  * import java.io.*;
42*0c56280aSSorin Basca  *
43*0c56280aSSorin Basca  * public class HelloWorld {
44*0c56280aSSorin Basca  *     public static void main(String[] argv) {
45*0c56280aSSorin Basca  *         BufferedReader in   = new BufferedReader(new InputStreamReader(System.in));
46*0c56280aSSorin Basca  *         String name = null;
47*0c56280aSSorin Basca  *
48*0c56280aSSorin Basca  *         try {
49*0c56280aSSorin Basca  *             System.out.print("Please enter your name> ");
50*0c56280aSSorin Basca  *             name = in.readLine();
51*0c56280aSSorin Basca  *         } catch(IOException e) {
52*0c56280aSSorin Basca  *             System.out.println(e);
53*0c56280aSSorin Basca  *             return;
54*0c56280aSSorin Basca  *         }
55*0c56280aSSorin Basca  *
56*0c56280aSSorin Basca  *         System.out.println("Hello, " + name);
57*0c56280aSSorin Basca  *     }
58*0c56280aSSorin Basca  * }
59*0c56280aSSorin Basca  * </PRE>
60*0c56280aSSorin Basca  *
61*0c56280aSSorin Basca  * @version $Id$
62*0c56280aSSorin Basca  */
63*0c56280aSSorin Basca public class HelloWorldBuilder {
main(String[] argv)64*0c56280aSSorin Basca     public static void main(String[] argv) {
65*0c56280aSSorin Basca         ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object",
66*0c56280aSSorin Basca                 "<generated>", Constants.ACC_PUBLIC |
67*0c56280aSSorin Basca                 Constants.ACC_SUPER,
68*0c56280aSSorin Basca                 null);
69*0c56280aSSorin Basca         ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
70*0c56280aSSorin Basca         InstructionList il = new InstructionList();
71*0c56280aSSorin Basca         MethodGen mg = new MethodGen(Constants.ACC_STATIC |
72*0c56280aSSorin Basca                 Constants.ACC_PUBLIC,// access flags
73*0c56280aSSorin Basca                 Type.VOID,              // return type
74*0c56280aSSorin Basca                 new Type[]{            // argument types
75*0c56280aSSorin Basca                         new ArrayType(Type.STRING, 1)
76*0c56280aSSorin Basca                 },
77*0c56280aSSorin Basca                 new String[]{"argv"}, // arg names
78*0c56280aSSorin Basca                 "main", "HelloWorld",    // method, class
79*0c56280aSSorin Basca                 il, cp);
80*0c56280aSSorin Basca         InstructionFactory factory = new InstructionFactory(cg);
81*0c56280aSSorin Basca 
82*0c56280aSSorin Basca         ObjectType i_stream = new ObjectType("java.io.InputStream");
83*0c56280aSSorin Basca         ObjectType p_stream = new ObjectType("java.io.PrintStream");
84*0c56280aSSorin Basca 
85*0c56280aSSorin Basca         // Create BufferedReader object and store it in local variable `in'.
86*0c56280aSSorin Basca         il.append(factory.createNew("java.io.BufferedReader"));
87*0c56280aSSorin Basca         il.append(InstructionConstants.DUP); // Use predefined constant, i.e. flyweight
88*0c56280aSSorin Basca         il.append(factory.createNew("java.io.InputStreamReader"));
89*0c56280aSSorin Basca         il.append(InstructionConstants.DUP);
90*0c56280aSSorin Basca         il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC));
91*0c56280aSSorin Basca 
92*0c56280aSSorin Basca         // Call constructors, i.e. BufferedReader(InputStreamReader())
93*0c56280aSSorin Basca         il.append(factory.createInvoke("java.io.InputStreamReader", "<init>",
94*0c56280aSSorin Basca                 Type.VOID, new Type[]{i_stream},
95*0c56280aSSorin Basca                 Constants.INVOKESPECIAL));
96*0c56280aSSorin Basca         il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID,
97*0c56280aSSorin Basca                 new Type[]{new ObjectType("java.io.Reader")},
98*0c56280aSSorin Basca                 Constants.INVOKESPECIAL));
99*0c56280aSSorin Basca 
100*0c56280aSSorin Basca         // Create local variable `in'
101*0c56280aSSorin Basca         LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null);
102*0c56280aSSorin Basca         int in = lg.getIndex();
103*0c56280aSSorin Basca         lg.setStart(il.append(new ASTORE(in))); // `i' valid from here
104*0c56280aSSorin Basca 
105*0c56280aSSorin Basca         // Create local variable `name'
106*0c56280aSSorin Basca         lg = mg.addLocalVariable("name", Type.STRING, null, null);
107*0c56280aSSorin Basca         int name = lg.getIndex();
108*0c56280aSSorin Basca         il.append(InstructionConstants.ACONST_NULL);
109*0c56280aSSorin Basca         lg.setStart(il.append(new ASTORE(name))); // `name' valid from here
110*0c56280aSSorin Basca 
111*0c56280aSSorin Basca         // try { ...
112*0c56280aSSorin Basca         InstructionHandle try_start =
113*0c56280aSSorin Basca                 il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC));
114*0c56280aSSorin Basca 
115*0c56280aSSorin Basca         il.append(new PUSH(cp, "Please enter your name> "));
116*0c56280aSSorin Basca         il.append(factory.createInvoke("java.io.PrintStream", "print", Type.VOID,
117*0c56280aSSorin Basca                 new Type[]{Type.STRING}, Constants.INVOKEVIRTUAL));
118*0c56280aSSorin Basca         il.append(new ALOAD(in));
119*0c56280aSSorin Basca         il.append(factory.createInvoke("java.io.BufferedReader", "readLine",
120*0c56280aSSorin Basca                 Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
121*0c56280aSSorin Basca         il.append(new ASTORE(name));
122*0c56280aSSorin Basca 
123*0c56280aSSorin Basca         // Upon normal execution we jump behind exception handler, the target address is not known yet.
124*0c56280aSSorin Basca         GOTO g = new GOTO(null);
125*0c56280aSSorin Basca         InstructionHandle try_end = il.append(g);
126*0c56280aSSorin Basca 
127*0c56280aSSorin Basca         /* } catch() { ... }
128*0c56280aSSorin Basca          * Add exception handler: print exception and return from method
129*0c56280aSSorin Basca          */
130*0c56280aSSorin Basca         InstructionHandle handler =
131*0c56280aSSorin Basca                 il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC));
132*0c56280aSSorin Basca         // Little trick in order not to save exception object temporarily
133*0c56280aSSorin Basca         il.append(InstructionConstants.SWAP);
134*0c56280aSSorin Basca 
135*0c56280aSSorin Basca         il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[]{Type.OBJECT}, Constants.INVOKEVIRTUAL));
136*0c56280aSSorin Basca         il.append(InstructionConstants.RETURN);
137*0c56280aSSorin Basca         mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException"));
138*0c56280aSSorin Basca 
139*0c56280aSSorin Basca         // Normal code continues, now we can set the branch target of the GOTO that jumps over the handler code.
140*0c56280aSSorin Basca         InstructionHandle ih =
141*0c56280aSSorin Basca                 il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC));
142*0c56280aSSorin Basca         g.setTarget(ih);
143*0c56280aSSorin Basca 
144*0c56280aSSorin Basca         // String concatenation compiles to StringBuffer operations.
145*0c56280aSSorin Basca         il.append(factory.createNew(Type.STRINGBUFFER));
146*0c56280aSSorin Basca         il.append(InstructionConstants.DUP);
147*0c56280aSSorin Basca         il.append(new PUSH(cp, "Hello, "));
148*0c56280aSSorin Basca         il.append(factory.createInvoke("java.lang.StringBuffer", "<init>",
149*0c56280aSSorin Basca                 Type.VOID, new Type[]{Type.STRING},
150*0c56280aSSorin Basca                 Constants.INVOKESPECIAL));
151*0c56280aSSorin Basca         il.append(new ALOAD(name));
152*0c56280aSSorin Basca 
153*0c56280aSSorin Basca         // Concatenate strings using a StringBuffer and print them.
154*0c56280aSSorin Basca         il.append(factory.createInvoke("java.lang.StringBuffer", "append",
155*0c56280aSSorin Basca                 Type.STRINGBUFFER, new Type[]{Type.STRING},
156*0c56280aSSorin Basca                 Constants.INVOKEVIRTUAL));
157*0c56280aSSorin Basca         il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
158*0c56280aSSorin Basca                 Type.STRING, Type.NO_ARGS,
159*0c56280aSSorin Basca                 Constants.INVOKEVIRTUAL));
160*0c56280aSSorin Basca 
161*0c56280aSSorin Basca         il.append(factory.createInvoke("java.io.PrintStream", "println",
162*0c56280aSSorin Basca                 Type.VOID, new Type[]{Type.STRING},
163*0c56280aSSorin Basca                 Constants.INVOKEVIRTUAL));
164*0c56280aSSorin Basca 
165*0c56280aSSorin Basca         il.append(InstructionConstants.RETURN);
166*0c56280aSSorin Basca 
167*0c56280aSSorin Basca         mg.setMaxStack(5); // Needed stack size
168*0c56280aSSorin Basca         cg.addMethod(mg.getMethod());
169*0c56280aSSorin Basca 
170*0c56280aSSorin Basca         il.dispose(); // Reuse instruction handles
171*0c56280aSSorin Basca 
172*0c56280aSSorin Basca         // Add public <init> method, i.e. empty constructor
173*0c56280aSSorin Basca         cg.addEmptyConstructor(Constants.ACC_PUBLIC);
174*0c56280aSSorin Basca 
175*0c56280aSSorin Basca         // Get JavaClass object and dump it to file.
176*0c56280aSSorin Basca         try {
177*0c56280aSSorin Basca             cg.getJavaClass().dump("HelloWorld.class");
178*0c56280aSSorin Basca         } catch (IOException e) {
179*0c56280aSSorin Basca             System.err.println(e);
180*0c56280aSSorin Basca         }
181*0c56280aSSorin Basca     }
182*0c56280aSSorin Basca }
183