Simn / genjvm

13 stars 1 forks source link

Branching in constructor arguments doesn't work #17

Closed Simn closed 5 years ago

Simn commented 5 years ago
class Main {
    static public function main() {
        new Main(f ? 1 : 2);
    }

    function new(_) {}

    static var f = false;
}
java.lang.VerifyError: Inconsistent stackmap frames at branch target 13
Exception Details:
  Location:
    Main.main([Ljava/lang/String;)V @13: iconst_2
  Reason:
    Type uninitialized 0 (current frame, stack[0]) is not assignable to 'Main' (stack map, stack[0])

The problem is that in the JVM a new instruction causes the verification type of the stack item to be Uninitialized until the invokespecial instruction happens. My own stack handling doesn't respect that and sets the type to the actual verification type immediately.

I'll have to see how to handle this because my entire stack handling is based on signatures, and there's no signature for "uninitialized". I might have to encode this in the signature structure. There's TObjectInner which is unused and I don't think could appear on the stack, so that would be an option.

Simn commented 5 years ago

This is still not quite right. Setting only the top of the stack if not good enough if there is some dup going on.

Simn commented 5 years ago

Actually this if fine if we're a bit careful with how we dup things.