Last active
March 20, 2022 21:28
-
-
Save joinr/585d440199430f4343d785728140ef5f to your computer and use it in GitHub Desktop.
an exploration of int casting and long reads in clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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