You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Keegan Witt (JIRA)" <ji...@apache.org> on 2015/07/29 21:00:04 UTC

[jira] [Commented] (GROOVY-7526) Safe navigation broken on java fields with indy and @CompileStatic

    [ https://issues.apache.org/jira/browse/GROOVY-7526?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14646608#comment-14646608 ] 

Keegan Witt commented on GROOVY-7526:
-------------------------------------

I was able to reproduce this in both Gradle and Maven with GMavenPlus.  I'm not sure yet if this is helpful, but the bytecode for {{Controller.run()}} is
{noformat}
 0 invokestatic #34 <com/GroovyTool.getData>
 3 astore_1
 4 aload_1
 5 pop
 6 aload_1
 7 dup
 8 astore_2
 9 ifnull 19 (+10)
12 aload_2
13 invokevirtual #40 <com/GroovyTool$Data.getFieldData>
16 goto 20 (+4)
19 aconst_null
20 invokedynamic #54 <cast, BootstrapMethods #0>
25 ifeq 38 (+13)
28 getstatic #60 <java/lang/System.out>
31 ldc #62 <HAS JAVA TOOL DATA>
33 invokevirtual #68 <java/io/PrintStream.println>
36 aconst_null
37 pop
38 invokestatic #73 <com/JavaTool.getData>
41 astore_3
42 aload_3
43 pop
44 aload_3
45 dup
46 ifnonnull 52 (+6)
49 goto 55 (+6)
52 getfield #79 <com/JavaTool$Data.fieldData>
55 invokedynamic #54 <cast, BootstrapMethods #0>
60 ifeq 73 (+13)
63 getstatic #60 <java/lang/System.out>
66 ldc #81 <HAS GROOVY TOOL DATA>
68 invokevirtual #68 <java/io/PrintStream.println>
71 aconst_null
72 pop
73 return
{noformat}

Without indy, but with CompileStatic:
{noformat}
 0 invokestatic #34 <com/GroovyTool.getData>
 3 astore_1
 4 aload_1
 5 pop
 6 aload_1
 7 dup
 8 astore_2
 9 ifnull 19 (+10)
12 aload_2
13 invokevirtual #40 <com/GroovyTool$Data.getFieldData>
16 goto 20 (+4)
19 aconst_null
20 invokestatic #46 <org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.booleanUnbox>
23 ifeq 36 (+13)
26 getstatic #52 <java/lang/System.out>
29 ldc #54 <HAS GROOVY TOOL DATA>
31 invokevirtual #60 <java/io/PrintStream.println>
34 aconst_null
35 pop
36 invokestatic #65 <com/JavaTool.getData>
39 astore_3
40 aload_3
41 pop
42 aload_3
43 dup
44 ifnonnull 50 (+6)
47 goto 53 (+6)
50 getfield #71 <com/JavaTool$Data.fieldData>
53 invokestatic #46 <org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.booleanUnbox>
56 ifeq 69 (+13)
59 getstatic #52 <java/lang/System.out>
62 ldc #73 <HAS JAVA TOOL DATA>
64 invokevirtual #60 <java/io/PrintStream.println>
67 aconst_null
68 pop
69 return
{noformat}

Without CompileStatic, but with indy
{noformat}
 0 ldc #30 <com/GroovyTool>
 2 invokedynamic #44 <invoke, BootstrapMethods #0>
 7 invokedynamic #50 <cast, BootstrapMethods #1>
12 astore_1
13 aload_1
14 pop
15 aload_1
16 invokedynamic #57 <getProperty, BootstrapMethods #2>
21 invokedynamic #60 <cast, BootstrapMethods #1>
26 ifeq 44 (+18)
29 ldc #62 <java/lang/System>
31 invokedynamic #66 <getProperty, BootstrapMethods #3>
36 ldc #68 <HAS JAVA TOOL DATA>
38 invokedynamic #73 <invoke, BootstrapMethods #4>
43 pop
44 ldc #75 <com/JavaTool>
46 invokedynamic #44 <invoke, BootstrapMethods #0>
51 invokedynamic #78 <cast, BootstrapMethods #1>
56 astore_2
57 aload_2
58 pop
59 aload_2
60 invokedynamic #81 <getProperty, BootstrapMethods #2>
65 invokedynamic #60 <cast, BootstrapMethods #1>
70 ifeq 88 (+18)
73 ldc #62 <java/lang/System>
75 invokedynamic #66 <getProperty, BootstrapMethods #3>
80 ldc #83 <HAS GROOVY TOOL DATA>
82 invokedynamic #73 <invoke, BootstrapMethods #4>
87 pop
88 return
{noformat}

Neither CompileStatic or indy:
{noformat}
  0 invokestatic #23 <com/Controller.$getCallSiteArray>
  3 astore_1
  4 aload_1
  5 ldc #33 <0>
  7 aaload
  8 ldc #35 <com/GroovyTool>
 10 invokeinterface #41 <org/codehaus/groovy/runtime/callsite/CallSite.call> count 2
 15 ldc #43 <com/GroovyTool$Data>
 17 invokestatic #49 <org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType>
 20 checkcast #43 <com/GroovyTool$Data>
 23 astore_2
 24 aload_2
 25 pop
 26 aload_1
 27 ldc #50 <1>
 29 aaload
 30 aload_2
 31 invokeinterface #53 <org/codehaus/groovy/runtime/callsite/CallSite.callGetPropertySafe> count 2
 36 invokestatic #59 <org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.booleanUnbox>
 39 ifeq 65 (+26)
 42 aload_1
 43 ldc #60 <2>
 45 aaload
 46 aload_1
 47 ldc #61 <3>
 49 aaload
 50 ldc #63 <java/lang/System>
 52 invokeinterface #66 <org/codehaus/groovy/runtime/callsite/CallSite.callGetProperty> count 2
 57 ldc #68 <HAS GROOVY TOOL DATA>
 59 invokeinterface #71 <org/codehaus/groovy/runtime/callsite/CallSite.call> count 3
 64 pop
 65 aload_1
 66 ldc #72 <4>
 68 aaload
 69 ldc #74 <com/JavaTool>
 71 invokeinterface #41 <org/codehaus/groovy/runtime/callsite/CallSite.call> count 2
 76 ldc #76 <com/JavaTool$Data>
 78 invokestatic #49 <org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType>
 81 checkcast #76 <com/JavaTool$Data>
 84 astore_3
 85 aload_3
 86 pop
 87 aload_1
 88 ldc #77 <5>
 90 aaload
 91 aload_3
 92 invokeinterface #53 <org/codehaus/groovy/runtime/callsite/CallSite.callGetPropertySafe> count 2
 97 invokestatic #59 <org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.booleanUnbox>
100 ifeq 126 (+26)
103 aload_1
104 ldc #78 <6>
106 aaload
107 aload_1
108 ldc #79 <7>
110 aaload
111 ldc #63 <java/lang/System>
113 invokeinterface #66 <org/codehaus/groovy/runtime/callsite/CallSite.callGetProperty> count 2
118 ldc #81 <HAS JAVA TOOL DATA>
120 invokeinterface #71 <org/codehaus/groovy/runtime/callsite/CallSite.call> count 3
125 pop
126 return
{noformat}

> Safe navigation broken on java fields with indy and @CompileStatic
> ------------------------------------------------------------------
>
>                 Key: GROOVY-7526
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7526
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 2.4.3
>            Reporter: Matthew Turnbull
>            Priority: Minor
>         Attachments: groovy_test.tar.gz
>
>
> Trying to directly access a native Java object field, from a Groovy class compiled with invokedynamic and @CompileStatic, causes a "java.lang.VerifyError: Bad type on operand stack" error.
> I have reproduced this on Linux with Groovy 2.4.3/2.4.4 and Java 1.7.0_80 (64bit).
> {noformat}
> ~ $ cd /tmp/groovy_test/
> /tmp/groovy_test $ rm -f com/*.class
> /tmp/groovy_test $ javac com/*.java
> /tmp/groovy_test $ /opt/groovy-2.4.4/bin/groovyc --indy --configscript config.groovyc com/*.groovy
> /tmp/groovy_test $ java -cp .:/opt/groovy-2.4.4/lib/groovy-2.4.4.jar com.Test
> {noformat}
> {noformat}
> Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
> Exception Details:
>   Location:
>     com/Controller.run()V @55: invokedynamic
>   Reason:
>     Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 'java/lang/String'
>   Current Frame:
>     bci: @55
>     flags: { }
>     locals: { 'com/Controller', 'com/GroovyTool$Data', 'com/GroovyTool$Data', 'com/JavaTool$Data' }
>     stack: { 'java/lang/Object' }
>   Bytecode:
>     0000000: b800 224c 2b57 2b59 4dc6 000a 2cb6 0028
>     0000010: a700 0401 ba00 3600 0099 000d b200 3c12
>     0000020: 3eb6 0044 0157 b800 494e 2d57 2d59 c700
>     0000030: 06a7 0006 b400 4fba 0036 0000 9900 0db2
>     0000040: 003c 1251 b600 4401 57b1               
>   Stackmap Table:
>     append_frame(@19,Object[#36],Object[#36])
>     same_locals_1_stack_item_frame(@20,Object[#87])
>     same_frame(@38)
>     full_frame(@52,{Object[#2],Object[#36],Object[#36],Object[#75]},{Object[#75]})
>     same_locals_1_stack_item_frame(@55,Object[#4])
>     same_frame(@73)
> 	at java.lang.Class.getDeclaredConstructors0(Native Method)
> 	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2595)
> 	at java.lang.Class.getConstructor0(Class.java:2895)
> 	at java.lang.Class.newInstance(Class.java:354)
> 	at com.Test.loadController(Test.java:20)
> 	at com.Test.test(Test.java:30)
> 	at com.Test.main(Test.java:10)
> {noformat}
> Work arounds that I found:
> * Remove @CompileStatic
> * Disable --indy
> * Cast the safely navigated field to it's object type i.e. (String)data?.field
> * Define a getter method to use in lieu of the field.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)