Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

GenerateReflection.java

00001 import de.fub.bytecode.*;
00002 import de.fub.bytecode.classfile.*;
00003 import de.fub.bytecode.generic.*;
00004 import java.io.*;
00005 
00006 public class GenerateReflection {
00007   private static final int METHOD_COUNT                         = 0;
00008   private static final int EXECUTE_METHOD                       = 1;
00009   private static final int IS_METHOD_EXECUTABLE                 = 2;
00010   private static final int IS_METHOD_DETERMINISTIC              = 3;
00011   private static final int STATIC_METHOD_COUNT                  = 4;
00012   private static final int EXECUTE_STATIC_METHOD                = 5;
00013   private static final int IS_STATIC_METHOD_EXECUTABLE          = 6;
00014   private static final int IS_STATIC_METHOD_DETERMINISTIC       = 7;
00015 
00016   private static String packageName = null;
00017   private static boolean forceMethod = false;
00018   private static boolean forceStaticMethod = false;
00019 
00020   private static class GenerateVisitor extends EmptyVisitor {
00021     private int phase;
00022     private int counter = 0;
00023     private JavaClass jc;
00024     private PrintStream outfile;
00025 
00026     public GenerateVisitor(JavaClass j, int p, PrintStream o) {
00027       jc = j;
00028       phase = p;
00029       outfile = o;
00030     }
00031 
00032     public int getCounter() {
00033       return counter;
00034     }
00035 
00036     public void visitMethod(Method m) {
00037       if(m.isNative()) {
00038     switch(phase) {
00039       case METHOD_COUNT:
00040         if(m.isStatic()) return;
00041         counter++;
00042         break;
00043 
00044       case EXECUTE_METHOD:
00045         if(m.isStatic()) return;
00046         putEquals(m);
00047         putPop(m, false);
00048         putReturnNextPC();
00049         break;
00050 
00051       case IS_METHOD_EXECUTABLE:
00052         if(m.isStatic()) return;
00053         putEquals(m);
00054         putPeek(m);
00055         putReturnTrue();
00056         break;
00057 
00058       case IS_METHOD_DETERMINISTIC:
00059         if(m.isStatic()) return;
00060         putEquals(m);
00061         putPeek(m);
00062         putReturnTrue();
00063         break;
00064 
00065       case STATIC_METHOD_COUNT:
00066         if(!m.isStatic()) return;
00067         counter++;
00068         break;
00069 
00070       case EXECUTE_STATIC_METHOD:
00071         if(!m.isStatic()) return;
00072         putEquals(m);
00073         putPop(m, true);
00074         putReturnNextPC();
00075         break;
00076 
00077       case IS_STATIC_METHOD_EXECUTABLE:
00078         if(!m.isStatic()) return;
00079         putEquals(m);
00080         putPeek(m);
00081         putReturnTrue();
00082         break;
00083 
00084       case IS_STATIC_METHOD_DETERMINISTIC:
00085         if(!m.isStatic()) return;
00086         putEquals(m);
00087         putPeek(m);
00088         putReturnTrue();
00089         break;
00090     }
00091       }
00092     }
00093 
00094     private void putEquals(Method m) {
00095       outfile.println("    if(name.equals(\"" + jc.getClassName() + "." + m.getName() + m.getSignature() + "\")) {");
00096       outfile.println("      // throws a runtime exception for now");
00097       outfile.println("      throw new NativeMethodException(\"" + jc.getClassName() + "." + m.getName() + m.getSignature() + "\");");
00098       outfile.println("      // put your code here");
00099     }
00100 
00101     private void putReturnNextPC() {
00102       outfile.println("      // return th.getPC().getNext();");
00103       outfile.println("    }");
00104       outfile.println();
00105     }
00106 
00107     private void putReturnTrue() {
00108       outfile.println("      // return true;");
00109       outfile.println("    }");
00110       outfile.println();
00111     }
00112 
00113     private void putPop(Method m, boolean isStatic) {
00114       Type[] args = Type.getArgumentTypes(m.getSignature());
00115       int nargs = args.length;
00116 
00117       for(int i = nargs - 1; i >= 0; i--) {
00118     int t = args[i].getType();
00119 
00120     switch(t) {
00121       case Constants.T_BOOLEAN:
00122         outfile.println("      // boolean arg" + i + " = th.popBoolean();");
00123         break;
00124 
00125       case Constants.T_BYTE:
00126         outfile.println("      // byte arg" + i + " = th.popByte();");
00127         break;
00128 
00129       case Constants.T_CHAR:
00130         outfile.println("      // char arg" + i + " = th.popChar();");
00131         break;
00132 
00133       case Constants.T_DOUBLE:
00134         outfile.println("      // double arg" + i + " = th.popDouble();");
00135         break;
00136 
00137       case Constants.T_FLOAT:
00138         outfile.println("      // float arg" + i + " = th.popFloat();");
00139         break;
00140 
00141       case Constants.T_INT:
00142         outfile.println("      // int arg" + i + " = th.popInt();");
00143         break;
00144 
00145       case Constants.T_LONG:
00146         outfile.println("      // long arg" + i + " = th.popLong();");
00147         break;
00148 
00149       case Constants.T_REFERENCE:
00150       case Constants.T_ARRAY:
00151         outfile.println("      // ObjRef arg" + i + " = th.popObjRef();");
00152         break;
00153 
00154       case Constants.T_SHORT:
00155         outfile.println("      // short arg" + i + " = th.popShort();");
00156         break;
00157 
00158     }
00159 
00160     if(!isStatic)
00161       outfile.println("      // th.popObjRef(); // this");
00162       }
00163 
00164       int t = Type.getReturnType(m.getSignature()).getType();
00165 
00166       switch(t) {
00167     case Constants.T_BOOLEAN:
00168       outfile.println("      // boolean result;");
00169       outfile.println("      // th.pushBoolean(result);");
00170       break;
00171 
00172     case Constants.T_BYTE:
00173       outfile.println("      // byte result;");
00174       outfile.println("      // th.pushByte(result);");
00175       break;
00176 
00177     case Constants.T_CHAR:
00178       outfile.println("      // char result;");
00179       outfile.println("      // th.pushChar(result);");
00180       break;
00181 
00182     case Constants.T_DOUBLE:
00183       outfile.println("      // double result;");
00184       outfile.println("      // th.pushDouble(result);");
00185       break;
00186 
00187     case Constants.T_FLOAT:
00188       outfile.println("      // float result;");
00189       outfile.println("      // th.pushFloat(result);");
00190       break;
00191 
00192     case Constants.T_INT:
00193       outfile.println("      // int result;");
00194       outfile.println("      // th.pushInt(result);");
00195       break;
00196 
00197     case Constants.T_LONG:
00198       outfile.println("      // long result;");
00199       outfile.println("      // th.pushLong(result);");
00200       break;
00201 
00202     case Constants.T_REFERENCE:
00203     case Constants.T_ARRAY:
00204       outfile.println("      // ObjRef result;");
00205       outfile.println("      // th.pushObjRef(result);");
00206       break;
00207 
00208     case Constants.T_SHORT:
00209       outfile.println("      // short result;");
00210       outfile.println("      // th.pushShort(result);");
00211       break;
00212       }
00213     }
00214 
00215     private void putPeek(Method m) {
00216       Type[] args = Type.getArgumentTypes(m.getSignature());
00217       int nargs = args.length;
00218 
00219       for(int i = nargs - 1; i >= 0; i--) {
00220     int t = args[i].getType();
00221 
00222     switch(t) {
00223       case Constants.T_BOOLEAN:
00224         outfile.println("      // boolean arg" + i + " = th.peekBoolean(" + i + ");");
00225         break;
00226 
00227       case Constants.T_BYTE:
00228         outfile.println("      // byte arg" + i + " = th.peekByte(" + i + ");");
00229         break;
00230 
00231       case Constants.T_CHAR:
00232         outfile.println("      // char arg" + i + " = th.peekChar(" + i + ");");
00233         break;
00234 
00235       case Constants.T_DOUBLE:
00236         outfile.println("      // double arg" + i + " = th.peekDouble(" + i + ");");
00237         break;
00238 
00239       case Constants.T_FLOAT:
00240         outfile.println("      // float arg" + i + " = th.peekFloat(" + i + ");");
00241         break;
00242 
00243       case Constants.T_INT:
00244         outfile.println("      // int arg" + i + " = th.peekInt(" + i + ");");
00245         break;
00246 
00247       case Constants.T_LONG:
00248         outfile.println("      // long arg" + i + " = th.peekLong(" + i + ");");
00249         break;
00250 
00251       case Constants.T_REFERENCE:
00252       case Constants.T_ARRAY:
00253         outfile.println("      // ObjRef arg" + i + " = th.peekObjRef(" + i + ");");
00254         break;
00255 
00256       case Constants.T_SHORT:
00257         outfile.println("      // short arg" + i + " = th.peekShort(" + i + ");");
00258         break;
00259 
00260     }
00261       }
00262     }
00263   }
00264   
00265   private static int generate(JavaClass j, int p, PrintStream o) {
00266     GenerateVisitor gv = new GenerateVisitor(j, p, o);
00267     new DefaultVisitor(j, gv).visit();
00268 
00269     return gv.getCounter();
00270   }  
00271   private static String getFileName(String name) {
00272     int index = 0;
00273     int last = 0;
00274     StringBuffer sb = new StringBuffer();
00275 
00276     while((index = name.indexOf(".", last)) != -1) {
00277       sb.append(Character.toUpperCase(name.charAt(last)));
00278       sb.append(name.substring(last + 1, index));
00279       last = index + 1;
00280     }
00281     sb.append(name.substring(last));
00282 
00283     return sb.toString();
00284   }  
00285   public static void main(String[] args) {
00286     int argc = args.length;
00287 
00288     if(argc == 0) {
00289       System.err.println("usage:");
00290       System.err.println("\tjava GenerateReflection [ -package <package> ] [ -force-methods ] [ -force-static-methods ] <classname> {<classname> ...}");
00291       System.err.println();
00292       return;
00293     }
00294 
00295     for(int i = 0; i < argc; i++)
00296       if(args[i].startsWith("-")) {
00297     if(args[i].equals("-package")) {
00298       packageName = args[++i];
00299     } else if(args[i].equals("-force-methods")) {
00300       forceMethod = true;
00301     } else if(args[i].equals("-force-static-methods")) {
00302       forceStaticMethod = true;
00303     } else {
00304       System.err.println("invalid option -- " + args[i]);
00305       System.exit(1);
00306     }
00307       } else
00308     process(args[i]);
00309   }  
00310   private static void process(String name) {
00311     try {
00312       System.out.println(name + ":");
00313       
00314       PrintStream outfile = new PrintStream(new FileOutputStream(getFileName(name) + "Reflection.java"));
00315       
00316       JavaClass jc;
00317 
00318       if((jc = Repository.lookupClass(name)) == null)
00319         jc = new ClassParser(name).parse();
00320 
00321       int nMethods = generate(jc, METHOD_COUNT, null);
00322       int nStaticMethods = generate(jc, STATIC_METHOD_COUNT, null);
00323 
00324       if(nMethods != 0 || nStaticMethods != 0 || forceMethod || forceStaticMethod) {
00325     if(packageName != null) {
00326       outfile.println("package " + packageName + ";");
00327       outfile.println();
00328     }
00329     outfile.println("import gov.nasa.arc.ase.jpf.jvm.*;");
00330     outfile.println("import gov.nasa.arc.ase.jpf.jvm.reflection.*;");
00331     outfile.println("import de.fub.bytecode.generic.InstructionHandle;");
00332     outfile.println();
00333     outfile.println("public class " + getFileName(name) + "Reflection extends Reflection {");
00334     if(nMethods != 0 || forceMethod) {
00335       outfile.println("  public InstructionHandle executeMethod(MethodInfo mi, boolean atomic) {");
00336       outfile.println("    String name = mi.getFullName();");
00337       outfile.println();
00338 
00339       generate(jc, EXECUTE_METHOD, outfile);
00340 
00341       outfile.println("    return super.executeMethod(mi, atomic);");
00342       outfile.println("  }");
00343       outfile.println();
00344       outfile.println("  public boolean isMethodExecutable(MethodInfo mi) {");
00345       outfile.println("    String name = mi.getFullName();");
00346       outfile.println();
00347 
00348       generate(jc, IS_METHOD_EXECUTABLE, outfile);
00349 
00350       outfile.println("    return super.isMethodExecutable(mi);");
00351       outfile.println("  }");
00352       outfile.println();
00353       outfile.println("  public boolean isMethodDeterministic(MethodInfo mi) {");
00354       outfile.println("    String name = mi.getFullName();");
00355       outfile.println();
00356 
00357       generate(jc, IS_METHOD_DETERMINISTIC, outfile);
00358 
00359       outfile.println("    return super.isMethodDeterministic(mi);");
00360       outfile.println("  }");
00361     }
00362     if(nStaticMethods != 0 || forceStaticMethod) {
00363       outfile.println("  public InstructionHandle executeStaticMethod(MethodInfo mi, boolean atomic) {");
00364       outfile.println("    String name = mi.getFullName();");
00365       outfile.println();
00366 
00367       generate(jc, EXECUTE_STATIC_METHOD, outfile);
00368 
00369       outfile.println("    return super.executeStaticMethod(mi, atomic);");
00370       outfile.println("  }");
00371       outfile.println();
00372       outfile.println("  public boolean isStaticMethodExecutable(MethodInfo mi) {");
00373       outfile.println("    String name = mi.getFullName();");
00374       outfile.println();
00375 
00376       generate(jc, IS_STATIC_METHOD_EXECUTABLE, outfile);
00377 
00378       outfile.println("    return super.isStaticMethodExecutable(mi);");
00379       outfile.println("  }");
00380       outfile.println();
00381       outfile.println("  public boolean isStaticMethodDeterministic(MethodInfo mi) {");
00382       outfile.println("    String name = mi.getFullName();");
00383       outfile.println();
00384 
00385       generate(jc, IS_STATIC_METHOD_DETERMINISTIC, outfile);
00386 
00387       outfile.println("    return super.isStaticMethodDeterministic(mi);");
00388       outfile.println("  }");
00389     }
00390     outfile.println("}");
00391       }
00392     } catch(IOException e) {
00393       e.printStackTrace();
00394       System.exit(1);
00395     }
00396   }  
00397 }

Generated at Thu Feb 7 06:45:55 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001