Using cacao from Debian Squeeze, easily reproducible - just get http://linux.ee/~mzz/yeti/yeti-icast.jar and try running it with -e argument to evaluate expression. predator:~/yeti$ java -cacao -jar yeti-icast.jar -e 42 LOG: [0x00007f6dea83e700] We received a SIGSEGV and tried to handle it, but we were LOG: [0x00007f707d7ba700] unable to find a Java method at: LOG: [0x00007f707d7ba700] LOG: [0x00007f707d7ba700] PC=0x00007f707c770425 LOG: [0x00007f707d7ba700] LOG: [0x00007f707d7ba700] Dumping the current stacktrace: at yeti.lang.compiler.eval$evaluateYetiCode$._0(Lyeti/lang/compiler/YetiEval;Lye ti/lang/MList;Ljava/util/List;[Ljava/lang/Object;Lyeti/lang/Fun;Ljava/lang/Object;Ljava/ lang/String;Lyeti/lang/compiler/CompileCtx;)Ljava/lang/Object;(eval.yeti:0) at yeti.lang.compiler.eval$evaluateYetiCode$.apply(Ljava/lang/Object;Ljava/lang/ Object;)Ljava/lang/Object;(eval.yeti:323) at yeti.lang.Fun2_.apply(Ljava/lang/Object;)Ljava/lang/Object;(NULL:0) at yeti.lang.compiler.yeti.main([Ljava/lang/String;)V(yeti.yeti:189) LOG: [0x00007f707d7ba700] Exiting... Aborted There is another problem also - differently from OpenJDK the Cacao expects that INVOKEINTERFACE object argument is statically determined to be instance of the interface that is invoked. For example, the following bytecode is fine with OpenJDK: public final java.lang.Object apply(java.lang.Object); Code: 0: aload_1 1: aconst_null 2: astore_1 3: ldc #13; //String a 5: invokeinterface #19, 2; //InterfaceMethod yeti/lang/Struct.get:(Ljava/lang/String;)Ljava/lang/Object; 10: areturn While Cacao gives the error that Exception in thread "main" java.lang.LinkageError: subtype constraint violated (java.lang.Object is not a subclass of yeti/lang/Struct). It seems to expect a explicit checkcast of the object reference (I'm not sure, it may be right about that according to the VM specification). The compiler currently omits those casts by default, because there would be really many of those and OpenJDK (nor Sun/Oracle JVM based on it or JRockit) doesn't seem to require it. This could be tested with http://linux.ee/~mzz/yeti/yeti.jar
After a lot of head scratching, I've found the problem, and it doesn't look pretty. It's some weird register allocation stuff going on, of the kind that comes back from the dead to haunt you. And I guarantee you, nobody really understands the CACAO register allocator :(. Method yeti.lang.compiler.eval$evaluateYetiCode$._1 84: aconst_null 85: astore 5 87: aconst_null 88: astore 7 90: aload 4 92: aload_0 93: invokevirtual #213; //Method yeti/lang/compiler/CompileCtx.enumWarns:(Lyeti/lang/Fun;)V 96: aload 7 98: ifnonnull 104 101: aload 5 103: areturn 104: aload 7 106: athrow There is a basic block boundary between 87 and 88, because 88 is an exception handler target; the code for 85-88 looks like this: 0x00002aaaabb79f72: 4c 89 7c 24 28 mov %r15,0x28(%rsp) 0x00002aaaabb79f77: 4d 31 ff xor %r15,%r15 == BB Boundary 0x00002aaaabb79f7a: 49 89 c7 mov %rax,%r15 0x00002aaaabb79f7d: 4c 89 7c 24 38 mov %r15,0x38(%rsp) It should store NULL to local variable 7, but it does in fact store whatever happens to be in register rax.
Out of curiosity: which compiler was used to produce that bytecode?
It was created by Yeti compiler (which is actually inside that jar). http://mth.github.com/yeti/
Comment #1 by firstname.lastname@example.org on 2011-07-22 10:40:47