Skip to content

Instantly share code, notes, and snippets.

@joinr
Last active March 20, 2022 21:28
Show Gist options
  • Save joinr/585d440199430f4343d785728140ef5f to your computer and use it in GitHub Desktop.
Save joinr/585d440199430f4343d785728140ef5f to your computer and use it in GitHub Desktop.
an exploration of int casting and long reads in clojure
(require '[clj-java-decompiler.core :refer [decompile disassemble]])
(require '[primitive-math])
(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)
(decompile
(fn []
(let [xs (int-array 10)
idx 0]
(aset xs idx 0))))
;; // Decompiling class: user$fn_line_2__215
;; import clojure.lang.*;
;; public final class user$fn_line_2__215 extends AFunction
;; {
;; public static final Object const__1;
;; public static Object invokeStatic() {
;; final Object xs = Numbers.int_array(user$fn_line_2__215.const__1);
;; final long idx = 0L;
;; return RT.aset((int[])xs, RT.intCast(idx), RT.intCast(0L));
;; }
;; @Override
;; public Object invoke() {
;; return invokeStatic();
;; }
;; static {
;; const__1 = 10L;
;; }
;; }
(decompile
(fn []
(let [xs (int-array 10)]
(aset xs 0 0))))
;; // Decompiling class: user$fn_line_2__225
;; import clojure.lang.*;
;; public final class user$fn_line_2__225 extends AFunction
;; {
;; public static final Object const__1;
;; public static Object invokeStatic() {
;; final Object xs = Numbers.int_array(user$fn_line_2__225.const__1);
;; return RT.aset((int[])xs, (int)0L, RT.uncheckedIntCast(0L));
;; }
;; @Override
;; public Object invoke() {
;; return invokeStatic();
;; }
;; static {
;; const__1 = 10L;
;; }
;; }
(disassemble
(fn []
(let [xs (int-array 10)]
(aset xs 0 0))))
;; // Decompiling class: user$fn_line_2__235
;; class user$fn_line_2__235
;; Minor version: 0
;; Major version: 52
;; Flags: PUBLIC, FINAL, SUPER
;; public static final java.lang.Object const__1;
;; Flags: PUBLIC, STATIC, FINAL
;; public void <init>();
;; Flags: PUBLIC
;; Code:
;; linenumber 1
;; 0: aload_0
;; 1: invokespecial clojure/lang/AFunction.<init>:()V
;; 4: return
;; public static java.lang.Object invokeStatic();
;; Flags: PUBLIC, STATIC
;; Code:
;; linenumber 1
;; 0: getstatic user$fn_line_2__235.const__1:Ljava/lang/Object;
;; linenumber 1
;; 3: invokestatic clojure/lang/Numbers.int_array:(Ljava/lang/Object;)[I
;; 6: astore_0 /* xs */
;; 7: aload_0 /* xs */
;; 8: checkcast [I
;; 11: lconst_0
;; linenumber 1
;; 12: l2i
;; 13: lconst_0
;; 14: invokestatic clojure/lang/RT.uncheckedIntCast:(J)I
;; linenumber 1
;; 17: invokestatic clojure/lang/RT.aset:([III)I
;; 20: invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
;; 23: areturn
;; public java.lang.Object invoke();
;; Flags: PUBLIC
;; Code:
;; linenumber 1
;; 0: invokestatic user$fn_line_2__235.invokeStatic:()Ljava/lang/Object;
;; 3: areturn
;; static {};
;; Flags: PUBLIC, STATIC
;; Code:
;; linenumber 1
;; 0: ldc2_w 10
;; 3: invokestatic java/lang/Long.valueOf:(J)Ljava/lang/Long;
;; 6: putstatic user$fn_line_2__235.const__1:Ljava/lang/Object;
;; 9: return
;; nil
(decompile
(fn []
(let [arr (int-array 10)
l (alength arr)]
(loop [idx (int 0)
acc (int 0)]
(if (< idx l)
(do
(recur (unchecked-inc idx)
(unchecked-inc acc)))
acc)))))
// Decompiling class: user$fn_line_2__256
import clojure.lang.*;
public final class user$fn_line_2__256 extends AFunction
{
public static final Object const__1;
public static Object invokeStatic() {
final Object arr = Numbers.int_array(user$fn_line_2__256.const__1);
final int l = ((int[])arr).length;
long idx = (int)0L;
long acc = (int)0L;
while (idx < l) {
final long n = idx + 1L;
++acc;
idx = n;
}
return Numbers.num(acc);
}
@Override
public Object invoke() {
return invokeStatic();
}
static {
const__1 = 10L;
}
}
(disassemble
(fn []
(let [arr (int-array 10)
l (alength arr)]
(loop [idx (int 0)
acc (int 0)]
(if (< idx l)
(do
(recur (unchecked-inc idx)
(unchecked-inc acc)))
acc)))))
// Decompiling class: user$fn_line_2__260
class user$fn_line_2__260
Minor version: 0
Major version: 52
Flags: PUBLIC, FINAL, SUPER
public static final java.lang.Object const__1;
Flags: PUBLIC, STATIC, FINAL
public void <init>();
Flags: PUBLIC
Code:
linenumber 1
0: aload_0
1: invokespecial clojure/lang/AFunction.<init>:()V
4: return
public static java.lang.Object invokeStatic();
Flags: PUBLIC, STATIC
Code:
linenumber 1
0: getstatic user$fn_line_2__260.const__1:Ljava/lang/Object;
linenumber 1
3: invokestatic clojure/lang/Numbers.int_array:(Ljava/lang/Object;)[I
6: astore_0 /* arr */
7: aload_0 /* arr */
8: checkcast [I
linenumber 1
11: arraylength
12: istore_1 /* l */
13: lconst_0
linenumber 1
14: l2i
linenumber 0
15: i2l
16: lstore_2 /* idx */
17: lconst_0
linenumber 1
18: l2i
linenumber 0
19: i2l
20: lstore acc
linenumber 1
22: lload_2 /* idx */
23: iload_1 /* l */
24: i2l
25: lcmp
26: ifge 46
29: lload_2 /* idx */
linenumber 1
30: lconst_1
31: ladd
32: lload acc
linenumber 1
34: lconst_1
35: ladd
36: lstore acc
38: lstore_2 /* idx */
39: goto 22
42: nop
43: nop
44: athrow
45: athrow
46: lload acc
48: invokestatic clojure/lang/Numbers.num:(J)Ljava/lang/Number;
51: areturn
StackMapTable: 00 04 FF 00 16 00 04 07 00 17 01 04 04 00 00 FF 00 13 00 00 00 01 07 00 23 42 07 00 23 FF 00 00 00 04 07 00 17 01 04 04 00 00
public java.lang.Object invoke();
Flags: PUBLIC
Code:
linenumber 1
0: invokestatic user$fn_line_2__260.invokeStatic:()Ljava/lang/Object;
3: areturn
static {};
Flags: PUBLIC, STATIC
Code:
linenumber 1
0: ldc2_w 10
3: invokestatic java/lang/Long.valueOf:(J)Ljava/lang/Long;
6: putstatic user$fn_line_2__260.const__1:Ljava/lang/Object;
9: return
;;Primitive math doesn't save us.
(decompile
(fn []
(let [arr (int-array 10)
l (alength arr)]
(loop [idx (int 0)
acc (int 0)]
(if (< idx l)
(do
(recur (primitive-math/inc idx)
(primitive-math/inc acc)))
acc)))))
import clojure.lang.*;
import primitive_math.*;
public final class user$fn_line_2__553 extends AFunction
{
public static final Object const__1;
public static Object invokeStatic() {
final Object arr = Numbers.int_array(user$fn_line_2__553.const__1);
final int l = ((int[])arr).length;
long idx = (int)0L;
long acc = (int)0L;
while (idx < l) {
final long inc = Primitives.inc(idx);
acc = Primitives.inc(acc);
idx = inc;
}
return Numbers.num(acc);
}
@Override
public Object invoke() {
return invokeStatic();
}
static {
const__1 = 10L;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment