2017-05-11 13 views
1

자바 바이트 코드를 생성하는 간단한 컴파일러를 만들고 싶습니다. 코드를 생성하기 위해 나는 Apache BCEL 라이브러리를 사용하고 있습니다.간단한 클래스 파일을 만들 때 메서드 시그니처에 대한 불법 상수 풀 인덱스

그러나 아무것도하지 않는 main 메소드로 간단한 클래스를 만드는 데 실패했습니다. 내가 클래스 파일을 생성하기 위해 다음 코드를 (내가 스칼라 것을 알고,하지만 당신은 나중에 살펴 보 겠지만 그게 그렇게 중요하지) 사용

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()); 
} 

클래스 파일이 생성 된 프로그램을 실행하지만 나는에게 피난처를

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

내가 자바 바이트 코드에 대해 읽기 및 상수 풀은 클래스 파일의 내용의 약 60 %이며, 이름의 모든 리터럴을 저장하는 것을 알고 있지만 : java MiniPascal을 실행할 때 나는 다음과 같은 예외가 예외의 경우는 아직 밝혀지지 않았다.

나는 당신의 제안을 기다리고 있습니다. 당신의 도움을 주셔서 감사합니다!

당신은 라인을 사용하여 클래스와 연관시키지 않습니다 자신의 빈 정수 풀 만드는

답변

2

: 당신이 상수 풀에 메소드 서명을 추가하지만, 그래서

val mainConstantPool: ConstantPoolGen = new ConstantPoolGen(); 

, 그것은 작동하지 않습니다 왜냐하면 상수 풀이 클래스 파일에 추가되지 않기 때문입니다.

먼저 상수 풀을 만들고 마지막 인수로 ClassGen 생성자에 전달하거나 mainConstantPoolclassFactory.getConstantPool()에서 초기화하십시오.