blob: b974a12b8b89efe837d93657c2fbee683ed2ae38 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.codehaus.groovy.classgen.asm.sc
import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase
/**
* Unit tests for static compilation: basic math operations.
*/
class StaticCompileMathTest extends AbstractBytecodeTestCase {
void testIntSum() {
assertScript '''
@groovy.transform.CompileStatic
int m() {
int a = 10
int b = 20
int c = a+b
}
assert m()==30
'''
}
void testLongSum() {
assertScript '''
@groovy.transform.CompileStatic
long m() {
long a = 10
long b = 20
long c = a+b
}
assert m()==30
'''
}
void testShortSum() {
assertScript '''
@groovy.transform.CompileStatic
int m() {
short a = 10
short b = 20
int c = a+b
}
assert m()==30
'''
}
void testFloatSum() {
assertScript '''
@groovy.transform.CompileStatic
float m() {
float a = 10f
float b = 20f
float c = a+b
}
assert m()==30f
'''
}
void testDoubleSum() {
assertScript '''
@groovy.transform.CompileStatic
double m() {
double a = 10d
double b = 20d
double c = a+b
}
assert m()==30d
'''
}
void testDoublePlusInt() {
assertScript '''
@groovy.transform.CompileStatic
double m() {
double a = 10d
int b = 1
double c = a+b
}
assert m()==11d
'''
}
void testIntMinusDouble() {
assertScript '''
@groovy.transform.CompileStatic
double m() {
int x = 10
double y = 0.5
x-y
}
assert m()==9.5d
'''
}
void testIntMinusBigDec() {
extractionOptions = [method: 'm', print:true]
assertScript '''
@groovy.transform.CompileStatic
double m() {
return 1i - 1.0 // 1.0 is BigDecimal
}
assert m()==0
'''
}
void testIntPlusBigDec() {
extractionOptions = [method: 'm', print:true]
assertScript '''
@groovy.transform.CompileStatic
double m() {
return 1i + 1.0 // 1.0 is BigDecimal
}
assert m()==2
'''
}
void testIntMultiplyBigDec() {
extractionOptions = [method: 'm', print:true]
assertScript '''
@groovy.transform.CompileStatic
double m() {
return 1i * 1.0 // 1.0 is BigDecimal
}
assert m()==1
'''
}
void testIntDivBigDec() {
extractionOptions = [method: 'm', print:true]
assertScript '''
@groovy.transform.CompileStatic
double m() {
return 1i / 1.0 // 1.0 is BigDecimal
}
assert m()==1
'''
}
void testStaticCompilePiComputationWithPrimitives() {
// extractionOptions = [method: 'doIt', print:true]
assertScript '''@groovy.transform.CompileStatic
def doIt() {
final int n = 10000000i // 10 times fewer due to speed issues.
final double delta = 1.0d / n
final startTime = System.nanoTime()
double sum = 0.0d
for (int i = 0; i < n; i++) { sum += 1.0d / (1.0d + ((i - 0.5d) * delta) ** 2i) }
final double pi = 4.0d * sum * delta
final elapseTime = (System.nanoTime() - startTime) / 1e9
println("==== Groovy Sequential Primitives pi = " + pi)
println("==== Groovy Sequential Primitives iteration count = " + n)
println("==== Groovy Sequential Primitives elapse = " + elapseTime)
}
doIt()
'''
}
void testStaticCompilePiComputationWithPrimitivesAndRangeLoop() {
// extractionOptions = [method: 'doIt', print:true]
assertScript '''@groovy.transform.CompileStatic
def doIt() {
final int n = 10000000i // 10 times fewer due to speed issues.
final double delta = 1.0d / n
final startTime = System.nanoTime()
double sum = 0.0d
for (int i in 1..n) { sum += 1.0d / (1.0d + ((i - 0.5d) * delta) ** 2i) }
final double pi = 4.0d * sum * delta
final elapseTime = (System.nanoTime() - startTime) / 1e9
println("==== Groovy Sequential Primitives pi = " + pi)
println("==== Groovy Sequential Primitives iteration count = " + n)
println("==== Groovy Sequential Primitives elapse = " + elapseTime)
}
doIt()
'''
}
void testStaticCompileLeftShiftEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 1
i <<= 2
i
}
assert foo()==4
'''
}
void testStaticCompileRightShiftEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 4
i >>= 2
i
}
assert foo()==1
'''
}
void testStaticCompilePlusEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 4
i += 2
i
}
assert foo()==6
'''
}
void testStaticCompileMinusEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 4
i -= 2
i
}
assert foo()==2
'''
}
void testStaticCompileDivideEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 4
i /= 2
i
}
assert foo()==2
'''
}
void testStaticCompileMultiplyEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 4
i *= 2
i
}
assert foo()==8
'''
}
void testStaticCompilePowerEquals() {
assertScript '''
@groovy.transform.CompileStatic
def foo() {
def i = 4
i **= 2
i
}
assert foo()==16
'''
}
void testStaticCompileModEquals() {
assertScript '''
@groovy.transform.CompileStatic
int foo() {
int i = 3
i %= 2
i
}
assert foo()==1
'''
}
void testPrimitiveIntCompareNotEqualShouldUseFastPath() {
def source = '''
@groovy.transform.CompileStatic
boolean cmp(int i, int j) {
boolean b = i==j
return i!=j
}
assert cmp(1,1) == false
assert cmp(1,2) == true
'''
assertScript(source)
def bytecode = compile(method:'cmp', source)
assert bytecode.hasStrictSequence([
'ILOAD 1',
'ILOAD 2',
'IF_ICMPNE'
])
}
void testPrimitiveLongCompareNotEqualShouldUseFastPath() {
def source = '''
@groovy.transform.CompileStatic
boolean cmp(long i, long j) {
boolean b = i==j
return i!=j
}
assert cmp(1,1) == false
assert cmp(1,2) == true
'''
assertScript(source)
def bytecode = compile(method:'cmp', source)
assert bytecode.hasStrictSequence([
'LLOAD 1',
'LLOAD 3',
'LCMP',
'IFNE'
])
}
}