예제 #1
0
  /**
   * Given the name of an interface <engineInterface> that a user wants to use for an engine, as
   * well as the name of a class <vmClass> that represents the vm, this does the following:
   *
   * <p>1. Checks that the given vm supports the interface. 2. Builds an engine and returns it.
   */
  public static FluidEngine buildEngine(String engineInterface, String vmClass) {
    // get class for <engineInterface>
    Class cEngine = null;
    try {
      cEngine = Class.forName(engineInterface);
    } catch (Exception e) {
      System.err.println("Could not find engine interface " + cEngine);
      e.printStackTrace();
      System.exit(1);
    }

    // get class for <vmClass>
    Class cVM = null;
    try {
      cVM = Class.forName(vmClass);
    } catch (Exception e) {
      System.err.println("Could not find VM " + cEngine);
      e.printStackTrace();
      System.exit(1);
    }

    // make a VM
    VM vm = null;
    try {
      vm = (VM) cVM.newInstance();
    } catch (Exception e) {
      System.err.println("Could not instantiate VM " + cEngine);
      e.printStackTrace();
      System.exit(1);
    }

    // check that the VM implements the interface
    VMUtils.checkInterface(cVM, cEngine);

    // build a version of the engine interface that calls back to
    // this basic engine for all its native methods
    BasicEngine result = buildCallbackEngine(engineInterface, cEngine);

    // do the setup for the resulting engine
    result.setup(vm);

    return result;
  }
예제 #2
0
  /**
   * Given class of the interface for a fluid engine, build a concrete instance of that interface
   * that calls back into a Basic Engine for all methods in the interface.
   */
  private static BasicEngine buildCallbackEngine(String engineInterface, Class cEngine) {
    // build up list of callbacks for <engineInterface>
    StringBuffer decls = new StringBuffer();
    Method[] engineMethods = cEngine.getMethods();
    for (int i = 0; i < engineMethods.length; i++) {
      Method meth = engineMethods[i];
      // skip methods that aren't declared in the interface
      if (meth.getDeclaringClass() != cEngine) {
        continue;
      }
      decls.append(
          "    public " + Utils.asTypeDecl(meth.getReturnType()) + " " + meth.getName() + "(");
      Class[] params = meth.getParameterTypes();
      for (int j = 0; j < params.length; j++) {
        decls.append(Utils.asTypeDecl(params[j]) + " p" + j);
        if (j != params.length - 1) {
          decls.append(", ");
        }
      }
      decls.append(") {\n");
      decls.append(
          "        return ("
              + Utils.asTypeDecl(meth.getReturnType())
              + ")super.callNative(\""
              + meth.getName()
              + "\", new Object[] {");
      for (int j = 0; j < params.length; j++) {
        decls.append("p" + j);
        if (j != params.length - 1) {
          decls.append(", ");
        }
      }
      decls.append("} );\n");
      decls.append("    }\n\n");
    }

    // write template file
    String engineName = "BasicEngine_" + engineInterface;
    String fileName = engineName + ".java";
    try {
      String contents = Utils.readFile("lava/engine/basic/BasicEngineTemplate.java").toString();
      // remove package name
      contents = Utils.replaceAll(contents, "package lava.engine.basic;", "");
      // for class decl
      contents =
          Utils.replaceAll(
              contents, "extends BasicEngine", "extends BasicEngine implements " + engineInterface);
      // for constructor
      contents = Utils.replaceAll(contents, "BasicEngineTemplate", engineName);
      // for methods
      contents = Utils.replaceAll(contents, "// INSERT METHODS HERE", decls.toString());
      Utils.writeFile(fileName, contents);
    } catch (IOException e) {
      e.printStackTrace();
      System.exit(1);
    }

    // compile the file
    try {
      Process jProcess = Runtime.getRuntime().exec("jikes " + fileName, null, null);
      jProcess.waitFor();
    } catch (Exception e) {
      System.err.println("Error compiling auto-generated file " + fileName);
      e.printStackTrace();
      System.exit(1);
    }

    // instantiate the class
    BasicEngine result = null;
    try {
      result = (BasicEngine) Class.forName(engineName).newInstance();
      // cleanup the files we made
      new File(engineName + ".java").delete();
      new File(engineName + ".class").delete();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }

    return result;
  }