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:01:04 UTC
[jira] [Comment Edited] (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 edited comment on GROOVY-7526 at 7/29/15 7:00 PM:
--------------------------------------------------------------
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 JAVA 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 GROOVY 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 JAVA 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 GROOVY TOOL DATA>
120 invokeinterface #71 <org/codehaus/groovy/runtime/callsite/CallSite.call> count 3
125 pop
126 return
{noformat}
was (Author: keegan):
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)