Skip to content

Commit b32e35a

Browse files
alexander-yakushevpuredanger
authored andcommitted
CLJ-2621: Make InstanceMethodExpr.emit discard unused primitive returns without boxing
Signed-off-by: Alex Miller <alex.miller@cognitect.com>
1 parent f5e5a4a commit b32e35a

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

src/jvm/clojure/lang/Compiler.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,8 +1612,16 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
16121612
gen.invokeInterface(type, m);
16131613
else
16141614
gen.invokeVirtual(type, m);
1615-
//if(context != C.STATEMENT || method.getReturnType() == Void.TYPE)
1616-
HostExpr.emitBoxReturn(objx, gen, method.getReturnType());
1615+
Class retClass = method.getReturnType();
1616+
if(context == C.STATEMENT)
1617+
{
1618+
if(retClass == long.class || retClass == double.class)
1619+
gen.pop2();
1620+
else if(retClass != void.class)
1621+
gen.pop();
1622+
}
1623+
else
1624+
HostExpr.emitBoxReturn(objx, gen, retClass);
16171625
}
16181626
else
16191627
{
@@ -1627,9 +1635,9 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
16271635
method.emitClearLocals(gen);
16281636
}
16291637
gen.invokeStatic(REFLECTOR_TYPE, invokeInstanceMethodMethod);
1638+
if(context == C.STATEMENT)
1639+
gen.pop();
16301640
}
1631-
if(context == C.STATEMENT)
1632-
gen.pop();
16331641
}
16341642

16351643
public boolean hasJavaClass(){

test/clojure/test_clojure/java_interop.clj

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
(:use clojure.test)
1414
(:require [clojure.inspector]
1515
[clojure.set :as set])
16-
(:import java.util.Base64))
16+
(:import java.util.Base64
17+
(java.util.concurrent.atomic AtomicLong AtomicInteger)))
1718

1819
; http://clojure.org/java_interop
1920
; http://clojure.org/compilation
@@ -589,3 +590,18 @@
589590
(is (= (char \a) \a)))
590591

591592
;; Note: More coercions in numbers.clj
593+
594+
; Test that primitive boxing elision in statement context works
595+
; correctly (CLJ-2621)
596+
597+
(defn inc-atomic-int [^AtomicInteger l]
598+
(.incrementAndGet l)
599+
nil)
600+
601+
(defn inc-atomic-long [^AtomicLong l]
602+
(.incrementAndGet l)
603+
nil)
604+
605+
(deftest test-boxing-prevention-when-compiling-statements
606+
(is (= 1 (.get (doto (AtomicInteger. 0) inc-atomic-int))))
607+
(is (= 1 (.get (doto (AtomicLong. 0) inc-atomic-long)))))

0 commit comments

Comments
 (0)