Пример #1
0
  private static void writeFile(
      ByteCodeClass cls, File outputDir, ConcatenatingFileOutputStream writeBufferInstead)
      throws Exception {
    OutputStream outMain =
        writeBufferInstead != null
                && ByteCodeTranslator.output == ByteCodeTranslator.OutputType.OUTPUT_TYPE_IOS
            ? writeBufferInstead
            : new FileOutputStream(
                new File(
                    outputDir, cls.getClsName() + "." + ByteCodeTranslator.output.extension()));

    if (outMain instanceof ConcatenatingFileOutputStream) {
      ((ConcatenatingFileOutputStream) outMain).beginNextFile(cls.getClsName());
    }
    if (ByteCodeTranslator.output == ByteCodeTranslator.OutputType.OUTPUT_TYPE_IOS) {
      outMain.write(cls.generateCCode(classes).getBytes());
      outMain.close();

      // we also need to write the header file for iOS
      String headerName = cls.getClsName() + ".h";
      FileOutputStream outHeader = new FileOutputStream(new File(outputDir, headerName));
      outHeader.write(cls.generateCHeader().getBytes());
      outHeader.close();
    } else {
      outMain.write(cls.generateCSharpCode().getBytes());
      outMain.close();
    }
  }
Пример #2
0
 public static ByteCodeClass getClassObject(String name) {
   for (ByteCodeClass cls : classes) {
     if (cls.getClsName().equals(name)) {
       return cls;
     }
   }
   return null;
 }
Пример #3
0
 private static ByteCodeClass getClassByName(String name) {
   name = name.replace('/', '_').replace('$', '_');
   for (ByteCodeClass bc : classes) {
     if (bc.getClsName().equals(name)) {
       return bc;
     }
   }
   return null;
 }
Пример #4
0
  public static void writeOutput(File outputDirectory) throws Exception {
    System.out.println("outputDirectory is: " + outputDirectory.getAbsolutePath());
    if (ByteCodeClass.getMainClass() == null) {
      System.out.println(
          "Error main class is not defined. The main class name is expected to have a public static void main(String[]) method and it is assumed to reside in the com.package.name directory");
      System.exit(1);
    }
    String file = "Unknown File";
    try {
      for (ByteCodeClass bc : classes) {
        // special case for object
        if (bc.getClsName().equals("java_lang_Object")) {
          continue;
        }
        file = bc.getClsName();
        bc.setBaseClassObject(getClassByName(bc.getBaseClass()));
        List<ByteCodeClass> lst = new ArrayList<ByteCodeClass>();
        for (String s : bc.getBaseInterfaces()) {
          ByteCodeClass bcode = getClassByName(s);
          if (bcode == null) {
            System.out.println(
                "Error while working with the class: "
                    + s
                    + " file:"
                    + file
                    + " no class definition");
          } else {
            lst.add(getClassByName(s));
          }
        }
        bc.setBaseInterfacesObject(lst);
      }
      for (ByteCodeClass bc : classes) {
        file = bc.getClsName();
        bc.updateAllDependencies();
      }
      ByteCodeClass.markDependencies(classes);
      classes = ByteCodeClass.clearUnmarked(classes);

      // load the native sources (including user native code)
      readNativeFiles(outputDirectory);

      // loop over methods and start eliminating the body of unused methods
      eliminateUnusedMethods();

      generateClassAndMethodIndexHeader(outputDirectory);

      boolean concatenate = "true".equals(System.getProperty("concatenateFiles", "false"));
      ConcatenatingFileOutputStream cos =
          concatenate ? new ConcatenatingFileOutputStream(outputDirectory) : null;

      for (ByteCodeClass bc : classes) {
        file = bc.getClsName();
        writeFile(bc, outputDirectory, cos);
      }
      if (cos != null) cos.realClose();

    } catch (Throwable t) {
      System.out.println("Error while working with the class: " + file);
      t.printStackTrace();
      if (t instanceof Exception) {
        throw (Exception) t;
      }
      if (t instanceof RuntimeException) {
        throw (RuntimeException) t;
      }
    }
  }
Пример #5
0
  private static void generateClassAndMethodIndexHeader(File outputDirectory) throws Exception {
    int classOffset = 0;
    int methodOffset = 0;
    ArrayList<BytecodeMethod> methods = new ArrayList<BytecodeMethod>();
    for (ByteCodeClass bc : classes) {
      bc.setClassOffset(classOffset);
      classOffset++;

      methodOffset = bc.updateMethodOffsets(methodOffset);
      methods.addAll(bc.getMethods());
    }

    StringBuilder bld = new StringBuilder();
    StringBuilder bldM = new StringBuilder();
    bldM.append("#include \"cn1_class_method_index.h\"\n");
    bldM.append("#include \"cn1_globals.h\"\n\n");
    bld.append("#ifndef __CN1_CLASS_METHOD_INDEX_H__\n#define __CN1_CLASS_METHOD_INDEX_H__\n\n");

    bld.append("// maps to offsets in the constant pool below\nextern int classNameLookup[];\n");
    bldM.append("// maps to offsets in the constant pool below\nint classNameLookup[] = {");
    boolean first = true;
    for (ByteCodeClass bc : classes) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append(addToConstantPool(bc.getClsName().replace('_', '.')));
      bldM.append("");
    }
    bldM.append("};\n\n");

    for (ByteCodeClass bc : classes) {
      bld.append("#define cn1_class_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(bc.getClassOffset());
      bld.append("\n");
    }

    int arrayId = classes.size() + 1;

    bld.append("#define cn1_array_start_offset ");
    bld.append(arrayId);
    bld.append("\n");

    // leave space for primitive arrays
    arrayId += 100;

    for (ByteCodeClass bc : classes) {
      bld.append("#define cn1_array_1_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;

      bld.append("#define cn1_array_2_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;

      bld.append("#define cn1_array_3_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;

      /*bld.append("#define cn1_array_4_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;*/
    }

    bld.append("\n\n");

    bld.append("// maps to offsets in the constant pool below\nextern int methodNameLookup[];\n");
    bldM.append("// maps to offsets in the constant pool below\nint methodNameLookup[] = {");
    first = true;
    for (BytecodeMethod m : methods) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append(addToConstantPool(m.getMethodName()));
      bldM.append("");
    }
    bldM.append("};\n\n");

    ArrayList<Integer> instances = new ArrayList<Integer>();
    int counter = 0;
    for (ByteCodeClass bc : classes) {
      /*bld.append("extern int classInstanceOfArr");
      bld.append(counter);
      bld.append("[];\n");*/
      bldM.append("int classInstanceOfArr");
      bldM.append(counter);
      bldM.append("[] = {");
      counter++;
      appendClassOffset(bc, instances);

      for (Integer i : instances) {
        bldM.append(i);
        bldM.append(", ");
      }
      instances.clear();
      bldM.append("-1};\n");
    }
    bld.append("extern int *classInstanceOf[];\n");
    bldM.append("int *classInstanceOf[");
    bldM.append(classes.size());
    bldM.append("] = {");
    first = true;
    counter = 0;
    for (ByteCodeClass bc : classes) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append("classInstanceOfArr");
      bldM.append(counter);
      counter++;
    }
    bldM.append("};\n\n");

    bld.append("#define CN1_CONSTANT_POOL_SIZE ");
    bld.append(constantPool.size());
    bld.append("\n\nextern const char * const constantPool[];\n");

    bldM.append("\n\nconst char * const constantPool[] = {\n");
    first = true;
    int offset = 0;
    for (String con : constantPool) {
      if (first) {
        bldM.append("\n    \"");
      } else {
        bldM.append(",\n    \"");
      }
      first = false;
      try {
        bldM.append(encodeString(con));
      } catch (Throwable t) {
        t.printStackTrace();
        System.out.println("Error writing the constant pool string: '" + con + "'");
        System.exit(1);
      }
      bldM.append("\" /* ");
      bldM.append(offset);
      offset++;
      bldM.append(" */");
    }
    bldM.append("};\n\nint classListSize = ");
    bldM.append(classes.size());
    bldM.append(";\n");

    for (ByteCodeClass bc : classes) {
      bldM.append("extern struct clazz class__");
      bldM.append(bc.getClsName().replace('/', '_').replace('$', '_'));
      bldM.append(";\n");
    }
    bldM.append("\n\nstruct clazz* classesList[] = {");
    first = true;
    for (ByteCodeClass bc : classes) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append("    &class__");
      bldM.append(bc.getClsName().replace('/', '_').replace('$', '_'));
    }
    bldM.append("};\n\n\n");

    // generate the markStatics method
    for (ByteCodeClass bc : classes) {
      bc.appendStaticFieldsExtern(bldM);
    }
    bldM.append(
        "\n\nextern int recursionKey;\nvoid markStatics(CODENAME_ONE_THREAD_STATE) {\n    recursionKey++;\n");
    for (ByteCodeClass bc : classes) {
      bc.appendStaticFieldsMark(bldM);
    }
    bldM.append("}\n\n");

    bld.append("\n\n#endif // __CN1_CLASS_METHOD_INDEX_H__\n");

    FileOutputStream fos =
        new FileOutputStream(new File(outputDirectory, "cn1_class_method_index.h"));
    fos.write(bld.toString().getBytes("UTF-8"));
    fos.close();
    fos = new FileOutputStream(new File(outputDirectory, "cn1_class_method_index.m"));
    fos.write(bldM.toString().getBytes("UTF-8"));
    fos.close();
  }