java.lang.VerifyError: (класс: Main, метод: main signature: ([Ljava / lang / String;) V) Слишком большой размер стека - PullRequest
1 голос
/ 05 декабря 2010

Я изучал библиотеку ASM.Сначала я написал программу для создания класса hello world, а затем подумал, что попробую что-то более сложное, создам класс, который создает PythonInterpreter (часть библиотеки Jython) и выполняет файл python.В результате получается следующее, к сожалению, я получаю исключение, после которого я назвал этот вопрос, когда пытаюсь выполнить результирующий класс.

public class Main {
public static void main(String[] args) {
    String mainFile = "main.py";

    ClassWriter mainClass = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    mainClass.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Main", null, "java/lang/Object", null);
    MethodVisitor mainMethod = mainClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);

    mainMethod.visitTypeInsn(Opcodes.NEW, "org/python/util/PythonInterpreter");
    mainMethod.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/python/util/PythonInterpreter", "<init>", "()V");

    mainMethod.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    mainMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/python/util/PythonInterpreter", "setOut", "(Ljava/io/PrintStream;)V");
    mainMethod.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
    mainMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/python/util/PythonInterpreter", "setErr", "(Ljava/io/PrintStream;)V");

    mainMethod.visitLdcInsn(mainFile);
    mainMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/python/util/PythonInterpreter", "execFile", "(Ljava/lang/String;)V");
    mainMethod.visitInsn(Opcodes.RETURN);

    mainMethod.visitEnd();
    mainClass.visitEnd();

    try{
        byte[] b = mainClass.toByteArray();
        FileOutputStream writer = new FileOutputStream("Main.class");
        writer.write(b);
        writer.close();
    }catch(IOException e){
        e.printStackTrace();
    }
}

}

1 Ответ

1 голос
/ 05 декабря 2010

Когда вы переходите к методам setOut и setErr, у вас есть только аргумент и нет объекта для вызова метода.(Вызов <init> «потребляет» объект, который он инициализировал!)

То же самое относится и к вызову execFile.У вас есть аргумент (mainFile), но нет объекта для вызова execFile.

Попробуйте добавить три DUP инструктино сразу после NEW.(Чтобы сохранить достаточно ссылок для трех вызовов методов, которые вы хотите выполнить для этого объекта.)

...