GenPeer.java :  » Code-Analyzer » javapathfinder » gov » nasa » jpf » tools » Java Open Source

Java Open Source » Code Analyzer » javapathfinder 
javapathfinder » gov » nasa » jpf » tools » GenPeer.java
//
// Copyright (C) 2005 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
// 
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file NOSA-1.3-JPF at the top of the distribution
// directory tree for the complete NOSA document.
// 
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
package gov.nasa.jpf.tools;

import gov.nasa.jpf.jvm.Types;

import java.io.PrintWriter;

import java.lang.reflect.*;

import java.util.ArrayList;


/**
 * tool to automatically generate the framework of a native peer MJI class,
 * given it's model class. GenPeer collects all the native methods from the 
 * model class, and creates the corresponding native peer methods
 */
public class GenPeer {
  static final String SYS_PKG = "gov.nasa.jpf.jvm";
  static final String MJI_ENV = "gov.nasa.jpf.jvm.MJIEnv";
  static final String INDENT = "  ";
  static final String METHOD_PREFIX = "public static";
  static final String ENV_ARG = "MJIEnv env";
  static final String OBJ_ARG = "int robj";
  static final String CLS_ARG = "int rcls";
  static final String REF_TYPE = "int";
  static final String NULL = "MJIEnv.NULL";
  static final String EXEC_COND = "$isExecutable_";
  static final String DETERM_COND = "$isDeterministic_";
  static String       clsName;
  static String[]     mths;

  // our options
  static boolean isSystemPkg;
  static boolean allMethods;
  static boolean mangleNames;
  static boolean clinit;
  static boolean execCond;
  static boolean determCond;

  public static void main (String[] args) {
    if ((args.length == 0) || !readOptions(args)) {
      showUsage();

      return;
    }

    PrintWriter pw = new PrintWriter(System.out, true);
    Class       cls = getClass(clsName);

    if (cls != null) {
      printNativePeer(cls, pw);
    }
  }

  static Class getClass (String cname) {
    Class clazz = null;

    try {
      clazz = Class.forName(cname);
    } catch (ClassNotFoundException cnfx) {
      System.err.println("target class not found: " + cname);
    } catch (Throwable x) {
      x.printStackTrace();
    }

    return clazz;
  }

  static boolean isMJICandidate (Method m) {
    if (allMethods) {
      return true;
    }

    if (mths != null) {
      String name = m.getName();

      for (int i = 0; i < mths.length; i++) {
        if (name.equals(mths[i])) {
          return true;
        }
      }
    } else {
      if ((m.getModifiers() & Modifier.NATIVE) != 0) {
        return true;
      }
    }

    return false;
  }

  static void getMangledName (Method m) {
    StringBuffer sb = new StringBuffer(50);

    sb.append(m.getName());
    sb.append("__");
  }

  static boolean isPrimitiveType (String t) {
    return ("int".equals(t) || "long".equals(t) || "boolean".equals(t) || 
           "void".equals(t) || // not really, but useful for returnTypes
           "byte".equals(t) || "char".equals(t) || "short".equals(t) || 
           "float".equals(t) || "double".equals(t));
  }

  static void printClinit (PrintWriter pw) {
    pw.print(INDENT);
    pw.print(METHOD_PREFIX);
    pw.print(" void $clinit (");
    pw.print(ENV_ARG);
    pw.print(", ");
    pw.print(CLS_ARG);
    pw.println(") {");
    pw.print(INDENT);
    pw.println("}");
  }

  static void printFooter (Class cls, PrintWriter pw) {
    pw.println("}");
  }

  static void printHeader (Class cls, PrintWriter pw) {
    if (isSystemPkg) {
      pw.print("package ");
      pw.print(SYS_PKG);
      pw.println(';');
      pw.println();

      pw.print("import ");
      pw.print(MJI_ENV);
      pw.println(";");
      pw.println();
    }

    String cname = cls.getName().replace('.', '_');

    pw.print("class ");
    pw.print("JPF_");
    pw.print(cname);
    pw.println(" {");
  }

  static void printMethodBody (String rt, String t, PrintWriter pw) {
    if (!"void".equals(rt)) {
      pw.print(INDENT);
      pw.print(INDENT);
      pw.print(rt);

      if ((rt == REF_TYPE) && (rt != t)) {
        pw.print(" r");
        pw.print(t);
        pw.print(" = ");
        pw.print(NULL);
        pw.println(";");

        pw.print(INDENT);
        pw.print(INDENT);
        pw.print("return r");
        pw.print(t);
        pw.println(";");
      } else {
        pw.print(" v = (");
        pw.print(rt);
        pw.println(")0;");

        pw.print(INDENT);
        pw.print(INDENT);
        pw.println("return v;");
      }
    }
  }

  static void printMethodName (Method m, PrintWriter pw) {
    String name = null;

    if (mangleNames) {
      name = Types.getJNIMangledMethodName(m);
    } else {
      name = m.getName();
    }

    pw.print(name);
  }

  static void printMethodStub (String condPrefix, Method m, PrintWriter pw) {
    String t = null;
    String rt;

    pw.print(INDENT);
    pw.print(METHOD_PREFIX);
    pw.print(' ');

    if (condPrefix == null) {
      t = rt = stripType(m.getReturnType().getName());

      if (!isPrimitiveType(rt)) {
        rt = REF_TYPE;
      }
    } else {
      rt = "boolean";
    }

    pw.print(rt);

    pw.print(' ');

    if (condPrefix != null) {
      pw.print(condPrefix);
    }

    printMethodName(m, pw);
    pw.print(" (");

    printStdArgs(m, pw);
    printTargetArgs(m, pw);

    pw.println(") {");

    if (condPrefix == null) {
      printMethodBody(rt, stripType(null, t), pw);
    } else {
      pw.print(INDENT);
      pw.print(INDENT);
      pw.println("return true;");
    }

    pw.print(INDENT);
    pw.println('}');
  }

  static void printNativePeer (Class cls, PrintWriter pw) {
    Method[] mths = cls.getDeclaredMethods();

    printHeader(cls, pw);

    if (clinit) {
      printClinit(pw);
    }

    for (int i = 0; i < mths.length; i++) {
      Method m = mths[i];

      if (isMJICandidate(m)) {
        if (determCond) {
          pw.println();
          printMethodStub(DETERM_COND, m, pw);
        }

        if (execCond) {
          pw.println();
          printMethodStub(EXEC_COND, m, pw);
        }

        pw.println();
        printMethodStub(null, m, pw);
      }
    }

    printFooter(cls, pw);
  }

  static void printStdArgs (Method m, PrintWriter pw) {
    pw.print(ENV_ARG);
    pw.print(", ");

    if ((m.getModifiers() & Modifier.STATIC) != 0) {
      pw.print(CLS_ARG);
    } else {
      pw.print(OBJ_ARG);
    }
  }

  static void printTargetArgs (Method m, PrintWriter pw) {
    Class[] pt = m.getParameterTypes();

    for (int i = 0; i < pt.length; i++) {
      String  t = stripType(pt[i].getName());
      boolean isPrim = isPrimitiveType(t);

      pw.print(", ");

      if (isPrim) {
        pw.print(t);
        pw.print(" v");
        pw.print(i);
      } else {
        pw.print(REF_TYPE);
        pw.print(" r");
        pw.print(stripType(null, t));
        pw.print(i);
      }
    }
  }

  static String[] readNames (String[] args, int i) {
    ArrayList a = null;

    for (; (i < args.length) && (args[i].charAt(0) != '-'); i++) {
      if (a == null) {
        a = new ArrayList();
      }

      a.add(args[i]);
    }

    if (a != null) {
      String[] names = new String[a.size()];
      a.toArray(names);

      return names;
    }

    return null;
  }

  static boolean readOptions (String[] args) {
    for (int i = 0; i < args.length; i++) {
      String arg = args[i];

      if ("-s".equals(arg)) {
        isSystemPkg = true;
      } else if ("-m".equals(arg)) {
        mangleNames = true;
      } else if ("-a".equals(arg)) {
        allMethods = true;
      } else if ("-ci".equals(arg)) {
        clinit = true;
      } else if ("-dc".equals(arg)) {
        determCond = true;
      } else if ("-ec".equals(arg)) {
        execCond = true;
      } else if (arg.charAt(0) != '-') {
        // rather simple
        if (clsName == null) {
          clsName = arg;
        } else {
          mths = readNames(args, i);
          i += mths.length;
        }
      } else {
        System.err.println("unknown option: " + arg);
        showUsage();

        return false;
      }
    }

    return (clsName != null);
  }

  static void showUsage () {
    System.out.println(
          "usage:   'GenPeer [<option>..] <className> [<method>..]'");
    System.out.println("options:  -s  : system peer class (gov.nasa.jpf.jvm)");
    System.out.println("          -ci : create <clinit> MJI method");
    System.out.println("          -m  : create mangled method names");
    System.out.println(
          "          -a  : create MJI methods for all target class methods");
    System.out.println(
          "          -dc : create isDeterministic condition methods");
    System.out.println("          -de : create isExecutable condition methods");
    System.out.println("          -nd : mark methods as non-deterministic");
  }

  static String stripType (String s) {
    return stripType("java.lang", s);
  }

  static String stripType (String prefix, String s) {
    int i = s.lastIndexOf('.') + 1;
    int l = s.length() - 1;

    if (s.charAt(l) == ';') {
      s = s.substring(0, l);
    }

    if (prefix == null) {
      if (i == 0) {
        return s;
      } else {
        return s.substring(i);
      }
    } else {
      if (s.startsWith(prefix) && (prefix.length() + 1 == i)) {
        return s.substring(i);
      } else {
        return s;
      }
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.