2017-05-11 6 views
1

Je souhaite créer un compilateur simple qui génère le bytecode Java. Pour générer le code j'utilise la bibliothèque Apache BCEL.Index de pool constant non valide pour la signature de méthode lors de la création d'un fichier de classe simple

Cependant, j'ai échoué dans la création d'une classe simple avec une méthode principale qui ne fait rien. J'utilise le code suivant (je sais qu'il est Scala, mais ce n'est pas si important, comme vous le verrez plus tard) pour générer le fichier de classe:

private def generateClassFile(): Unit = 
{ 
    // JVM tutorial: https://commons.apache.org/proper/commons-bcel/manual/jvm.html 
    val interfaces: Array[String] = new Array(0); 
    classFactory = new ClassGen(
     "MiniPascal", 
     "java.lang.Object", 
     null, 
     Const.ACC_PUBLIC | Const.ACC_SUPER, 
     interfaces 
    ); 

    val mainConstantPool: ConstantPoolGen = new ConstantPoolGen(); 
    val mainMethod = generateMainMethod(mainConstantPool); 
    classFactory.addMethod(mainMethod.getMethod()); 
} 

private def generateMainMethod(mainConstantPool): MethodGen = 
{ 
    val instructions = new InstructionList(); 
    instructions.append(InstructionConstants.NOP); 

    mainConstantPool.addNameAndType("main", "([java/lang/String;)V"); 

    val methodArgumentNames = Array("args"); 
    val methodArgumentTypes: Array[Type] = Array(new ArrayType(Type.STRING, 1)); 
    val mainMethod: MethodGen = new MethodGen(
     Const.ACC_PUBLIC | Const.ACC_STATIC, 
     Type.VOID, 
     methodArgumentTypes, 
     methodArgumentNames, 
     "main", "MiniPascal", 
     instructions, 
     mainConstantPool 
    ); 

    return mainMethod; 
} 

private def saveClassFile(): Unit = 
{ 
    val classFile: JavaClass = classFactory.getJavaClass(); 
    classFile.dump("MiniPascal.class"); 
    //println(classFile.toString()); 
} 

Lors de l'exécution du programme du fichier de classe est générée, mais lors de l'exécution java MiniPascal je reçois l'exception suivante:

java.lang.ClassFormatError: Illegal constant pool index 4 for method signature in class file MiniPascal 

Je lis sur le bytecode Java et savent que la piscine constante est d'environ 60% du contenu d'un fichier de classe et stocke de tous les littéraux, mais je havre de paix au nom Ne pas comprendre le cas de l'exception pour le moment.

Je me réjouis de vos suggestions. Merci de votre aide!

Répondre

2

Vous créez votre propre piscine vide constant que vous n'associez pas avec la classe, en utilisant la ligne:

val mainConstantPool: ConstantPoolGen = new ConstantPoolGen(); 

Ainsi, bien que vous ajoutez la signature de la méthode à la piscine constante, il ne fonctionne pas car le pool constant n'est jamais ajouté au fichier de classe.

soit créer le pool constant premier et le transmettre au constructeur ClassGen comme le dernier argument, ou initialise mainConstantPool de classFactory.getConstantPool().