2015-09-29 4 views
3

Недавно я начал писать компилятор для своего собственного языка, но при запуске основного метода он начал вызывать исключение. Он работает с моими другими тестовыми классами, но он не хочет работать с этим. Насколько я могу судить, нет ничего другого в том, как метод вызывается между этим классом и другими. Вот исключение.java.lang.VerifyError при вызове конструктора

Exception in thread "main" java.lang.VerifyError: (class: FizzBuzz/FizzBuzz, method: <init> signature:()V) Incompatible object argument for function call 
at java.lang.Class.getDeclaredMethods0(Native Method) 
at java.lang.Class.privateGetDeclaredMethods(Class.java:2693) 
at java.lang.Class.privateGetMethodRecursive(Class.java:3040) 
at java.lang.Class.getMethod0(Class.java:3010) 
at java.lang.Class.getMethod(Class.java:1776) 
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544) 
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526) 

и вот выход байткод из javap

public final class FizzBuzz.FizzBuzz { 
    public FizzBuzz.FizzBuzz(); 
    Code: 
     0: new   #16     // class Lang/Int 
     3: dup 
     4: lconst_0 
     5: invokespecial #19     // Method Lang/Int."<init>":(J)V 
     8: astore_1 
     9: aload_1 
     10: new   #16     // class Lang/Int 
     13: dup 
     14: ldc2_w  #20     // long 100l 
     17: invokespecial #19     // Method Lang/Int."<init>":(J)V 
     20: invokevirtual #25     // Method Lang/Int._lessThan:(LLang/Number;)LLang/Boolean; 
     23: getfield  #31     // Field Lang/Boolean.value:Z 
     26: ifeq   140 
     29: ldc   #33     // String 
     31: astore_2 
     32: aload_1 
     33: new   #16     // class Lang/Int 
     36: dup 
     37: ldc2_w  #34     // long 3l 
     40: invokespecial #19     // Method Lang/Int."<init>":(J)V 
     43: invokevirtual #39     // Method Lang/Int._modulus:(LLang/Int;)LLang/Int; 
     46: new   #16     // class Lang/Int 
     49: dup 
     50: lconst_0 
     51: invokespecial #19     // Method Lang/Int."<init>":(J)V 
     54: invokevirtual #43     // Method Lang/Int._equals:(Ljava/lang/Object;)LLang/Boolean; 
     57: getfield  #31     // Field Lang/Boolean.value:Z 
     60: ifeq   70 
     63: aload_2 
     64: ldc   #45     // String Fizz 
     66: invokevirtual #51     // Method Lang/String._add:(LLang/String;)LLang/String; 
     69: astore_2 
     70: nop 
     71: aload_1 
     72: new   #16     // class Lang/Int 
     75: dup 
     76: ldc2_w  #52     // long 5l 
     79: invokespecial #19     // Method Lang/Int."<init>":(J)V 
     82: invokevirtual #39     // Method Lang/Int._modulus:(LLang/Int;)LLang/Int; 
     85: new   #16     // class Lang/Int 
     88: dup 
     89: lconst_0 
     90: invokespecial #19     // Method Lang/Int."<init>":(J)V 
     93: invokevirtual #43     // Method Lang/Int._equals:(Ljava/lang/Object;)LLang/Boolean; 
     96: getfield  #31     // Field Lang/Boolean.value:Z 
     99: ifeq   109 
    102: aload_2 
    103: ldc   #55     // String Buzz 
    105: invokevirtual #51     // Method Lang/String._add:(LLang/String;)LLang/String; 
    108: astore_2 
    109: nop 
    110: aload_2 
    111: invokevirtual #59     // Method Lang/String.isEmpty:()LLang/Boolean; 
    114: invokevirtual #62     // Method Lang/Boolean._not:()LLang/Boolean; 
    117: getfield  #31     // Field Lang/Boolean.value:Z 
    120: ifeq   127 
    123: aload_2 
    124: invokestatic #68     // Method Lang/System.println:(Ljava/lang/Object;)V 
    127: nop 
    128: aload_1 
    129: invokestatic #68     // Method Lang/System.println:(Ljava/lang/Object;)V 
    132: aload_1 
    133: invokevirtual #72     // Method Lang/Int._increment:()LLang/Int; 
    136: astore_1 
    137: goto   9 
    140: nop 
    141: aload_0 
    142: invokespecial #10     // Method java/lang/Object."<init>":()V 
    145: return 
    LocalVariableTable: 
     Start Length Slot Name Signature 
     141  5  0 this LFizzBuzz/FizzBuzz; 
      8  138  1  i LLang/Int; 
     31  115  2 str LLang/String; 

    public static void main(java.lang.String[]); 
    Code: 
     0: aload_0 
     1: invokestatic #80     // Method Lang/System.setArguments:([Ljava/lang/String;)V 
     4: new   #4     // class FizzBuzz/FizzBuzz 
     7: invokespecial #81     // Method "<init>":()V 
     10: return 
    LocalVariableTable: 
     Start Length Slot Name Signature 
      0  11  0 args [Ljava/lang/String; 
} 
+0

Когда вы вызываете основной метод или когда вы вызываете конструктор? Ваше название и тело не согласны. Это поможет, если вы можете показать байт-код, который терпит неудачу ... –

+0

Я вставил ваш вывод, так как вы не должны требовать от ваших читателей открывать внешние веб-сайты. – Holger

ответ

4

В своем коде, у вас есть последовательность

29: ldc   #33    // String 
    31: astore_2 
… 
    63: aload_2 
    64: ldc   #45    // String Fizz 
    66: invokevirtual #51    // Method Lang/String._add:(LLang/String;)LLang/String; 

Конечно, только потому, что ваш язык имеет другой String типа Безразлично» поэтому JVM использует ваш собственный тип, когда он встречает команду ldc. Сначала вам необходимо преобразовать экземпляр java/lang/String, созданный инструкцией ldc, к экземпляру Lang/String. Затем вы можете вызвать свой метод add.

Если ваш заказ String неизменен, и вы хотите реализовать компилировать постоянное время вашего языка в String с, вы можете использовать invokedynamic инструкции, указывающую на постоянная java/lang/String в качестве статического параметра. Метод bootstrap может затем преобразовать его в ваш тип строки и вернуть дескриптор константного метода. Поскольку метод bootstrap запускается только один раз при первом выполнении команды invokedynamic, вы получаете желаемое постоянное поведение.

+0

Я полностью забыл превратить строки java в свои собственные строки. Благодаря! – EnderShadow