Assigning long to value to Long field triggers VerifyError #45

Open
hakunin opened this Issue Jan 18, 2011 · 6 comments

Projects

None yet

3 participants

@hakunin
hakunin commented Jan 18, 2011

What I am doing here is oviously wrong, but this should be caught at compile time I think.

michal@domov:~/Dropbox/dev/usedriven$ mirah -e "@a = Long(nil); @a = Long.parseLong('1297')"
java/lang/Class.java:-2:in `getDeclaredMethods0': java.lang.VerifyError: (class: DashE, method: main signature: ([Ljava/lang/String;)V) Expecting to find object/array on stack (NativeException)
from java/lang/Class.java:2427:in `privateGetDeclaredMethods'
from java/lang/Class.java:2670:in `getMethod0'
from java/lang/Class.java:1603:in `getMethod'
from /home/michal/mystuff/mirah/lib/mirah.rb:128:in `run'
from /home/michal/mystuff/mirah/lib/mirah.rb:125:in `each'
from /home/michal/mystuff/mirah/lib/mirah.rb:125:in `run'
from /home/michal/mystuff/mirah/lib/mirah.rb:21:in `run'
from /home/michal/mystuff/mirah/bin/mirah:9
@consiliens
Contributor

"Comment 1 by rogerpack2005, May 28, 2011
probably a bug in the bytecode generator, as I think it works ok via mirahc then javac..."
http://code.google.com/p/mirah/issues/detail?id=21

@baroquebobcat
Member

I think this is conflating two issues.

  1. using @something in a static method
  2. Long & long

when I run

a= Long(nil);a=Long.parseLong("1234");

I get

Inference Error:
Can't assign long to variable of type java.lang.Long

for a response

@baroquebobcat
Member

Interestingly, while mirahc -e "@a = Long(nil); @a = Long.parseLong('1297')" gives you an invalid class file

$ mirahc -e "@a = Long(nil); @a = Long.parseLong('1297')"
Parsing...
  <inline script>
Inferring types...
Compiling...
  DashE
Done!
$ java -cp . DashE
Exception in thread "main" java.lang.VerifyError: (class: DashE, method: main signature: ([Ljava/lang/String;)V) Expecting to find object/array on stack

compiling to java source generates good output that compiles and runs correctly.

$ mirahc -j -e "@a = Long(nil); @a = Long.parseLong('1297')"

Parsing...
  <inline script>
Inferring types...
Compiling...
  DashE
Done!

$ javac -cp . DashE.java 
$ java -cp . DashE

DashE.java

// Generated from DashE
public class DashE extends java.lang.Object {
  private static java.lang.Long a;
  public static void main(java.lang.String[] argv) {
    DashE.a = ((java.lang.Long)(null));
    DashE.a = java.lang.Long.parseLong("1297");
  }
}
@baroquebobcat
Member

I think it's a type coercion issue because when you use Long.new(str) it works.

$ mirah -e "@a = Long(nil); @a = Long.new('1297'); puts @a"
1297
@baroquebobcat
Member

Ran it w/ -V with locals and fields. The relevant log line I think is this one

* [Mirah::Typer] Learned field type under  : a = Type(long)

currently, inference on field assignment doesn't do all the type checking it should.
https://github.com/mirah/mirah/blob/master/lib/mirah/typer/simple.rb#L152-159

      def learn_static_field_type(cls, name, type)
        log "Learned field type under #{cls} : #{name} = #{type}" if type

        # TODO check for compatibility?
        static_field_type_hash(cls)[name] ||= known_types[type] || type

        type
      end

local inference does, which is why you get an inference error rather than a runtime error.

The other interesting thing is that cls is nil. Which is probably contributing to the problem.

@baroquebobcat
Member

this is a boxing / unboxing problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment