Skip to content

Invoke compiled enum class file from dotr failed #7424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Eastsun opened this issue Oct 15, 2019 · 3 comments
Closed

Invoke compiled enum class file from dotr failed #7424

Eastsun opened this issue Oct 15, 2019 · 3 comments

Comments

@Eastsun
Copy link

Eastsun commented Oct 15, 2019

minimized code

enum A {
  case A1
}

~/enum-bug > ls
A.scala
 ~/enum-bug > cat A.scala
enum A {
  case A1
}%                                                                                                                               

~/enum-bug > dotc A.scala
~/enum-bug > dotc -version
Dotty compiler version 0.19.0-RC1 -- Copyright 2002-2019, LAMP/EPFL
~/enum-bug > dotr
Starting dotty REPL...
scala> A.values
java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    rs$line$1$.<init>()V @12: invokevirtual
  Reason:
    Type 'A$' (current frame, stack[1]) is not assignable to 'A'
  Current Frame:
    bci: @12
    flags: { }
    locals: { 'rs$line$1$' }
    stack: { 'rs$line$1$', 'A$' }
  Bytecode:
    0x0000000: 2ab7 0011 2ab3 0013 2ab2 0018 b600 1eb5
    0x0000010: 0020 b1

        at rs$line$1.res0(rs$line$1)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at dotty.tools.repl.Rendering.$anonfun$3(Rendering.scala:72)
        at scala.Option.map(Option.scala:242)
        at dotty.tools.repl.Rendering.valueOf(Rendering.scala:72)
        at dotty.tools.repl.Rendering.renderVal(Rendering.scala:95)
        at dotty.tools.repl.ReplDriver.displayMembers$3$$anonfun$3(ReplDriver.scala:285)
        at scala.collection.immutable.List.map(List.scala:219)
        at scala.collection.immutable.List.map(List.scala:79)
        at dotty.tools.repl.ReplDriver.displayMembers$6(ReplDriver.scala:285)
        at dotty.tools.repl.ReplDriver.displayDefinitions$$anonfun$3$$anonfun$2(ReplDriver.scala:311)
        at scala.Option.map(Option.scala:242)
        at dotty.tools.repl.ReplDriver.displayDefinitions$$anonfun$1(ReplDriver.scala:311)
        at dotty.tools.dotc.core.Phases.atPhase$$anonfun$1(Phases.scala:35)
        at dotty.tools.dotc.core.Periods.atPhase(Periods.scala:25)
        at dotty.tools.dotc.core.Phases.atPhase(Phases.scala:35)
        at dotty.tools.dotc.core.Contexts$Context.atPhase(Contexts.scala:71)
        at dotty.tools.repl.ReplDriver.displayDefinitions(ReplDriver.scala:317)
        at dotty.tools.repl.ReplDriver.compile$$anonfun$2(ReplDriver.scala:241)
        at scala.util.Either.fold(Either.scala:189)
        at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:241)
        at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:193)
        at dotty.tools.repl.ReplDriver.loop$1(ReplDriver.scala:127)
        at dotty.tools.repl.ReplDriver.runUntilQuit$$anonfun$1(ReplDriver.scala:130)
        at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:148)
        at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:130)
        at dotty.tools.repl.Main$.main(Main.scala:6)
        at dotty.tools.repl.Main.main(Main.scala)
@bishabosha
Copy link
Member

bishabosha commented Oct 31, 2019

The classfiles generated (with java -c -v -p)

rs$line$1$.class
Classfile rs$line$1$.class
  Last modified Oct 31, 2019; size 736 bytes
  MD5 checksum 1ce56dbdae438e10f3f08c9776ad8c0f
  Compiled from "rs$line$1"
public final class rs$line$1$ implements java.io.Serializable
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               rs$line$1$
   #2 = Class              #1             // rs$line$1$
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             // java/lang/Object
   #5 = Utf8               java/io/Serializable
   #6 = Class              #5             // java/io/Serializable
   #7 = Utf8               rs$line$1
   #8 = Utf8               MODULE$
   #9 = Utf8               Lrs$line$1$;
  #10 = Utf8               res0
  #11 = Utf8               [LA;
  #12 = Utf8               <clinit>
  #13 = Utf8               ()V
  #14 = Utf8               <init>
  #15 = NameAndType        #14:#13        // "<init>":()V
  #16 = Methodref          #2.#15         // rs$line$1$."<init>":()V
  #17 = Methodref          #4.#15         // java/lang/Object."<init>":()V
  #18 = NameAndType        #8:#9          // MODULE$:Lrs$line$1$;
  #19 = Fieldref           #2.#18         // rs$line$1$.MODULE$:Lrs$line$1$;
  #20 = Utf8               A$
  #21 = Class              #20            // A$
  #22 = Utf8               LA$;
  #23 = NameAndType        #8:#22         // MODULE$:LA$;
  #24 = Fieldref           #21.#23        // A$.MODULE$:LA$;
  #25 = Utf8               A
  #26 = Class              #25            // A
  #27 = Utf8               values
  #28 = Utf8               ()[LA;
  #29 = NameAndType        #27:#28        // values:()[LA;
  #30 = Methodref          #26.#29        // A.values:()[LA;
  #31 = NameAndType        #10:#11        // res0:[LA;
  #32 = Fieldref           #2.#31         // rs$line$1$.res0:[LA;
  #33 = Utf8               this
  #34 = Utf8               writeReplace
  #35 = Utf8               ()Ljava/lang/Object;
  #36 = Utf8               scala/runtime/ModuleSerializationProxy
  #37 = Class              #36            // scala/runtime/ModuleSerializationProxy
  #38 = Utf8               (Ljava/lang/Class;)V
  #39 = NameAndType        #14:#38        // "<init>":(Ljava/lang/Class;)V
  #40 = Methodref          #37.#39        // scala/runtime/ModuleSerializationProxy."<init>":(Ljava/lang/Class;)V
  #41 = Utf8               Code
  #42 = Utf8               LineNumberTable
  #43 = Utf8               LocalVariableTable
  #44 = Utf8               Signature
  #45 = Utf8               SourceFile
  #46 = Utf8               Scala
{
  public static final rs$line$1$ MODULE$;
    descriptor: Lrs$line$1$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL

  private final A[] res0;
    descriptor: [LA;
    flags: ACC_PRIVATE, ACC_FINAL

  public static {};
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: new           #2                  // class rs$line$1$
         3: invokespecial #16                 // Method "<init>":()V
         6: return

  private rs$line$1$();
    descriptor: ()V
    flags: ACC_PRIVATE
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #17                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #19                 // Field MODULE$:Lrs$line$1$;
         8: aload_0
         9: getstatic     #24                 // Field A$.MODULE$:LA$;
        12: invokevirtual #30                 // Method A.values:()[LA;
        15: putfield      #32                 // Field res0:[LA;
        18: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      19     0  this   Lrs$line$1$;

  private java.lang.Object writeReplace();
    descriptor: ()Ljava/lang/Object;
    flags: ACC_PRIVATE
    Code:
      stack=3, locals=1, args_size=1
         0: new           #37                 // class scala/runtime/ModuleSerializationProxy
         3: dup
         4: ldc           #2                  // class rs$line$1$
         6: invokespecial #40                 // Method scala/runtime/ModuleSerializationProxy."<init>":(Ljava/lang/Class;)V
         9: areturn
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      10     0  this   Lrs$line$1$;

  public A[] res0();
    descriptor: ()[LA;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #32                 // Field res0:[LA;
         4: areturn
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lrs$line$1$;
    Signature: #28                          // ()[LA;
}
SourceFile: "rs$line$1"
Error: unknown attribute
  Scala: length = 0x0
rs$line$1.class
Classfile rs$line$1.class
  Last modified Oct 31, 2019; size 243 bytes
  MD5 checksum 1a00ea90fe85ba440288651393c56a04
  Compiled from "rs$line$1"
public final class rs$line$1
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               rs$line$1
   #2 = Class              #1             // rs$line$1
   #3 = Utf8               java/lang/Object
   #4 = Class              #3             // java/lang/Object
   #5 = Utf8               res0
   #6 = Utf8               ()[LA;
   #7 = Utf8               rs$line$1$
   #8 = Class              #7             // rs$line$1$
   #9 = Utf8               MODULE$
  #10 = Utf8               Lrs$line$1$;
  #11 = NameAndType        #9:#10         // MODULE$:Lrs$line$1$;
  #12 = Fieldref           #8.#11         // rs$line$1$.MODULE$:Lrs$line$1$;
  #13 = NameAndType        #5:#6          // res0:()[LA;
  #14 = Methodref          #8.#13         // rs$line$1$.res0:()[LA;
  #15 = Utf8               Code
  #16 = Utf8               SourceFile
  #17 = Utf8               TASTY
  #18 = Utf8               Scala
{
  public static A[] res0();
    descriptor: ()[LA;
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #12                 // Field rs$line$1$.MODULE$:Lrs$line$1$;
         3: invokevirtual #14                 // Method rs$line$1$.res0:()[LA;
         6: areturn
}
SourceFile: "rs$line$1"
Error: unknown attribute
  TASTY: length = 0x10
   00 1D 3A DC 3F D7 A6 00 00 F9 DE 9C 42 F0 D1 00

Error: unknown attribute
  Scala: length = 0x0

@olofwalker
Copy link

olofwalker commented Nov 1, 2019

I guess I'm seeing the side effect of this ? using 0.19, defining an enum like this:

enum Verb
    case Init,Get,Edit,Add,Start,Done,Restart

and using valueOf method

 val verbType = Verb.valueOf("Get"))

an exception is thrown

[error] (run-main-8) java.lang.VerifyError: Bad type on operand stack
[error] Exception Details:
[error]   Location:
[error]     com/pharway/ting/Main$.main([Ljava/lang/String;)V @22: invokevirtual
[error]   Reason:pile / compile 0s
[error]     Type 'com/pharway/ting/Verb$' (current frame, stack[1]) is not assignable to 'com/pharway/ting/Verb'

@bishabosha bishabosha mentioned this issue Nov 5, 2019
22 tasks
@bishabosha
Copy link
Member

bishabosha commented Nov 7, 2019

So I've seen the culprit in the constructor of rs$line$1$, i.e. the object that contains the code entered by scala> A.values:

private rs$line$1$();
    descriptor: ()V
    flags: ACC_PRIVATE
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #17                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: putstatic     #19                 // Field MODULE$:Lrs$line$1$;
         8: aload_0
         9: getstatic     #24                 // Field A$.MODULE$:LA$;
        12: invokevirtual #30                 // Method A.values:()[LA;
        15: putfield      #32                 // Field res0:[LA;
        18: return

so you can see at address 12, there is invokevirtual on the static method A.Values:()[LA;, where the last object on the stack is A$.MODULE$

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

No branches or pull requests

4 participants