示例#1
0
 private static boolean checkMethodUsedByBaseClassOrInterface(
     BytecodeMethod mtd, ByteCodeClass cls) {
   if (cls == null) {
     return false;
   }
   if (cls.getBaseInterfacesObject() != null) {
     for (ByteCodeClass bc : cls.getBaseInterfacesObject()) {
       for (BytecodeMethod m : bc.getMethods()) {
         if (m.getMethodName().equals(mtd.getMethodName())) {
           if (m.isUsedByNative()) {
             return true;
           }
           break;
         }
       }
     }
   }
   for (BytecodeMethod m : cls.getMethods()) {
     if (m.getMethodName().equals(mtd.getMethodName())) {
       if (m.isUsedByNative()) {
         return true;
       }
       break;
     }
   }
   return false;
 }
示例#2
0
  private static boolean cullMethods(boolean found) {
    for (ByteCodeClass bc : classes) {
      bc.unmark();
      if (bc.isIsInterface() || bc.getBaseClass() == null) {
        continue;
      }
      for (BytecodeMethod mtd : bc.getMethods()) {
        if (mtd.isEliminated()
            || mtd.isUsedByNative()
            || mtd.isMain()
            || mtd.getMethodName().equals("__CLINIT__")
            || mtd.getMethodName().equals("finalize")
            || mtd.isNative()) {
          continue;
        }

        if (!isMethodUsed(mtd)) {
          if (isMethodUsedByBaseClassOrInterface(mtd, bc)) {
            continue;
          }
          found = true;
          mtd.setEliminated(true);
          /*if(ByteCodeTranslator.verbose) {
          System.out.println("Eliminating method: " + mtd.getClsName() + "." + mtd.getMethodName());
          }*/
        }
      }
    }
    return found;
  }
示例#3
0
  private static void usedByNativeCheck() {
    for (ByteCodeClass bc : classes) {
      // java_lang_Thread_runImpl___long
      for (BytecodeMethod mtd : bc.getMethods()) {
        // check native code
        StringBuilder b = new StringBuilder();
        mtd.appendFunctionPointer(b);
        String str = b.toString();

        for (String s : nativeSources) {
          if (s.contains(str)) {
            mtd.setUsedByNative(true);
            break;
          }
        }
      }
    }
  }
示例#4
0
 @Override
 public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
   int[] keys = new int[labels.length];
   int counter = min;
   for (int iter = 0; iter < keys.length; iter++) {
     keys[iter] = counter;
     counter++;
   }
   mtd.addSwitch(dflt, keys, labels);
   super.visitTableSwitchInsn(min, max, dflt, labels);
 }
示例#5
0
  private static boolean isMethodUsed(BytecodeMethod m) {
    for (ByteCodeClass bc : classes) {
      for (BytecodeMethod mtd : bc.getMethods()) {
        if (mtd.isEliminated() || mtd == m) {
          continue;
        }
        if (mtd.isMethodUsed(m)) {
          return true;
        }
      }
    }

    // check native code
    StringBuilder b = new StringBuilder();
    m.appendFunctionPointer(b);
    String str = b.toString();
    for (String s : nativeSources) {
      if (s.contains(str)) {
        return true;
      }
    }

    return false;
  }
示例#6
0
 @Override
 public void visitJumpInsn(int opcode, Label label) {
   mtd.addJump(opcode, label);
   super.visitJumpInsn(opcode, label);
 }
示例#7
0
 @Override
 public void visitLabel(Label label) {
   mtd.addLabel(label);
   super.visitLabel(label);
 }
示例#8
0
 @Override
 public void visitLdcInsn(Object cst) {
   mtd.addLdc(cst);
   super.visitLdcInsn(cst);
 }
示例#9
0
 @Override
 public void visitIincInsn(int var, int increment) {
   mtd.addIInc(var, increment);
   super.visitIincInsn(var, increment);
 }
示例#10
0
 @Override
 public void visitIntInsn(int opcode, int operand) {
   mtd.addVariableOperation(opcode, operand);
   super.visitIntInsn(opcode, operand);
 }
示例#11
0
 @Override
 public void visitTypeInsn(int opcode, String type) {
   mtd.addTypeInstruction(opcode, type);
   super.visitTypeInsn(opcode, type);
 }
示例#12
0
 @Override
 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
   mtd.addTryCatchBlock(start, end, handler, type);
   super.visitTryCatchBlock(start, end, handler, type);
 }
示例#13
0
 @Override
 public void visitLocalVariable(
     String name, String desc, String signature, Label start, Label end, int index) {
   mtd.addLocalVariable(name, desc, signature, start, end, index);
   super.visitLocalVariable(name, desc, signature, start, end, index);
 }
示例#14
0
 @Override
 public void visitLineNumber(int line, Label start) {
   mtd.addDebugInfo(line);
   super.visitLineNumber(line, start);
 }
示例#15
0
 @Override
 public void visitMaxs(int maxStack, int maxLocals) {
   mtd.setMaxes(maxStack, maxLocals);
   super.visitMaxs(maxStack, maxLocals);
 }
示例#16
0
 @Override
 public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
   mtd.addInvoke(opcode, owner, name, desc, itf);
   super.visitMethodInsn(opcode, owner, name, desc, itf);
 }
示例#17
0
 @Override
 public void visitFieldInsn(int opcode, String owner, String name, String desc) {
   mtd.addField(opcode, owner, name, desc);
   super.visitFieldInsn(opcode, owner, name, desc);
 }
示例#18
0
 @Override
 public void visitMultiANewArrayInsn(String desc, int dims) {
   mtd.addMultiArray(desc, dims);
   super.visitMultiANewArrayInsn(desc, dims);
 }
示例#19
0
 @Override
 public void visitVarInsn(int opcode, int var) {
   mtd.addVariableOperation(opcode, var);
   super.visitVarInsn(opcode, var);
 }
示例#20
0
 @Override
 public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
   mtd.addSwitch(dflt, keys, labels);
   super.visitLookupSwitchInsn(dflt, keys, labels);
 }
示例#21
0
 @Override
 public void visitInsn(int opcode) {
   mtd.addInstruction(opcode);
   super.visitInsn(opcode);
 }
示例#22
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();
  }