[ 
https://issues.apache.org/jira/browse/GROOVY-7656?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Shil Sinha resolved GROOVY-7656.
--------------------------------
    Resolution: Fixed

Merged

> Spread safe method calls on list literals result in the list expression being 
> evaluated twice (SC)
> --------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-7656
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7656
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 2.4.5
>            Reporter: Shil Sinha
>            Assignee: Shil Sinha
>            Priority: Critical
>             Fix For: 2.4.6
>
>
> When a list literal is the receiver for a statically compiled spread safe 
> method call expression, the instructions to create the list are included 
> twice. Example:
> {code}
> @groovy.transform.CompileStatic
> void test() {
>     ['a']*.size()
> }
> {code}
> The bytecode for the method above is:
> {code}
>  L0
>     LINENUMBER 3 L0
>     NEW java/util/ArrayList
>     DUP
>     INVOKESPECIAL java/util/ArrayList.<init> ()V
>     ASTORE 1
>    L1
>     ALOAD 1
>     POP
>     ICONST_1
>     ANEWARRAY java/lang/Object
>     DUP
>     ICONST_0
>     LDC "a"
>     AASTORE
>     INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.createList 
> ([Ljava/lang/Object;)Ljava/util/List;
>     IFNULL L2
>     ACONST_NULL
>     ASTORE 2
>    L3
>     ICONST_1
>     ANEWARRAY java/lang/Object
>     DUP
>     ICONST_0
>     LDC "a"
>     AASTORE
>     INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.createList 
> ([Ljava/lang/Object;)Ljava/util/List;
>     INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator;
>     ASTORE 3
>    L4
>     ALOAD 3
>     INVOKEINTERFACE java/util/Iterator.hasNext ()Z
>     IFEQ L2
>     ALOAD 3
>     INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;
>     ASTORE 2
>     ALOAD 1
>     ALOAD 2
>     DUP
>     ASTORE 4
>     IFNULL L5
>     ALOAD 4
>     INVOKESTATIC 
> org/codehaus/groovy/runtime/typehandling/ShortTypeHandling.castToString 
> (Ljava/lang/Object;)Ljava/lang/String;
>     CHECKCAST java/lang/String
>     INVOKESTATIC org/codehaus/groovy/runtime/StringGroovyMethods.size 
> (Ljava/lang/String;)I
>     INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
>     GOTO L6
>    L5
>     ACONST_NULL
>    L6
>     INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
>     POP
>     GOTO L4
>    L2
>     ALOAD 1
>     POP
> {code}
> If the list expression contains method calls that have side effects, this can 
> cause serious problems. The example below is trivial, but shows the general 
> case:
> {code}
> @groovy.transform.CompileStatic
> void test() {
>     def list = ['abc']
>     def lengths = [list.removeAt(0)]*.length() // throws 
> IndexOutOfBoundsException
> }
> {code}



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

Reply via email to